//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension NetworkFirewall {
    // MARK: Enums

    public enum AttachmentStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case creating = "CREATING"
        case deleting = "DELETING"
        case error = "ERROR"
        case failed = "FAILED"
        case ready = "READY"
        case scaling = "SCALING"
        public var description: String { return self.rawValue }
    }

    public enum ConfigurationSyncState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case capacityConstrained = "CAPACITY_CONSTRAINED"
        case inSync = "IN_SYNC"
        case pending = "PENDING"
        public var description: String { return self.rawValue }
    }

    public enum EnabledAnalysisType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case httpHost = "HTTP_HOST"
        case tlsSni = "TLS_SNI"
        public var description: String { return self.rawValue }
    }

    public enum EncryptionType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case awsOwnedKmsKey = "AWS_OWNED_KMS_KEY"
        case customerKms = "CUSTOMER_KMS"
        public var description: String { return self.rawValue }
    }

    public enum FirewallStatusValue: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case deleting = "DELETING"
        case provisioning = "PROVISIONING"
        case ready = "READY"
        public var description: String { return self.rawValue }
    }

    public enum FlowOperationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case completed = "COMPLETED"
        case completedWithErrors = "COMPLETED_WITH_ERRORS"
        case failed = "FAILED"
        case inProgress = "IN_PROGRESS"
        public var description: String { return self.rawValue }
    }

    public enum FlowOperationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case flowCapture = "FLOW_CAPTURE"
        case flowFlush = "FLOW_FLUSH"
        public var description: String { return self.rawValue }
    }

    public enum GeneratedRulesType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case alertlist = "ALERTLIST"
        case allowlist = "ALLOWLIST"
        case denylist = "DENYLIST"
        case rejectlist = "REJECTLIST"
        public var description: String { return self.rawValue }
    }

    public enum IPAddressType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dualstack = "DUALSTACK"
        case ipv4 = "IPV4"
        case ipv6 = "IPV6"
        public var description: String { return self.rawValue }
    }

    public enum IdentifiedType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case statelessRuleContainsTcpFlags = "STATELESS_RULE_CONTAINS_TCP_FLAGS"
        case statelessRuleForwardingAsymmetrically = "STATELESS_RULE_FORWARDING_ASYMMETRICALLY"
        public var description: String { return self.rawValue }
    }

    public enum LogDestinationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cloudwatchLogs = "CloudWatchLogs"
        case kinesisDataFirehose = "KinesisDataFirehose"
        case s3 = "S3"
        public var description: String { return self.rawValue }
    }

    public enum LogType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case alert = "ALERT"
        case flow = "FLOW"
        case tls = "TLS"
        public var description: String { return self.rawValue }
    }

    public enum OverrideAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case dropToAlert = "DROP_TO_ALERT"
        public var description: String { return self.rawValue }
    }

    public enum PerObjectSyncStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case capacityConstrained = "CAPACITY_CONSTRAINED"
        case inSync = "IN_SYNC"
        case pending = "PENDING"
        public var description: String { return self.rawValue }
    }

    public enum ResourceManagedStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case account = "ACCOUNT"
        case managed = "MANAGED"
        public var description: String { return self.rawValue }
    }

    public enum ResourceManagedType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case activeThreatDefense = "ACTIVE_THREAT_DEFENSE"
        case awsManagedDomainLists = "AWS_MANAGED_DOMAIN_LISTS"
        case awsManagedThreatSignatures = "AWS_MANAGED_THREAT_SIGNATURES"
        public var description: String { return self.rawValue }
    }

    public enum ResourceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case deleting = "DELETING"
        case error = "ERROR"
        public var description: String { return self.rawValue }
    }

    public enum RevocationCheckAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case drop = "DROP"
        case pass = "PASS"
        case reject = "REJECT"
        public var description: String { return self.rawValue }
    }

    public enum RuleGroupType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case stateful = "STATEFUL"
        case stateless = "STATELESS"
        public var description: String { return self.rawValue }
    }

    public enum RuleOrder: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case defaultActionOrder = "DEFAULT_ACTION_ORDER"
        case strictOrder = "STRICT_ORDER"
        public var description: String { return self.rawValue }
    }

    public enum StatefulAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case alert = "ALERT"
        case drop = "DROP"
        case pass = "PASS"
        case reject = "REJECT"
        public var description: String { return self.rawValue }
    }

    public enum StatefulRuleDirection: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case any = "ANY"
        case forward = "FORWARD"
        public var description: String { return self.rawValue }
    }

    public enum StatefulRuleProtocol: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case any = "IP"
        case dcerpc = "DCERPC"
        case dhcp = "DHCP"
        case dns = "DNS"
        case ftp = "FTP"
        case http = "HTTP"
        case http2 = "HTTP2"
        case icmp = "ICMP"
        case ikev2 = "IKEV2"
        case imap = "IMAP"
        case krb5 = "KRB5"
        case msn = "MSN"
        case ntp = "NTP"
        case quic = "QUIC"
        case smb = "SMB"
        case smtp = "SMTP"
        case ssh = "SSH"
        case tcp = "TCP"
        case tftp = "TFTP"
        case tls = "TLS"
        case udp = "UDP"
        public var description: String { return self.rawValue }
    }

    public enum StreamExceptionPolicy: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case `continue` = "CONTINUE"
        case drop = "DROP"
        case reject = "REJECT"
        public var description: String { return self.rawValue }
    }

    public enum SummaryRuleOption: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case metadata = "METADATA"
        case msg = "MSG"
        case sid = "SID"
        public var description: String { return self.rawValue }
    }

    public enum TCPFlag: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case ack = "ACK"
        case cwr = "CWR"
        case ece = "ECE"
        case fin = "FIN"
        case psh = "PSH"
        case rst = "RST"
        case syn = "SYN"
        case urg = "URG"
        public var description: String { return self.rawValue }
    }

    public enum TargetType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case httpHost = "HTTP_HOST"
        case tlsSni = "TLS_SNI"
        public var description: String { return self.rawValue }
    }

    public enum TransitGatewayAttachmentStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case creating = "CREATING"
        case deleted = "DELETED"
        case deleting = "DELETING"
        case error = "ERROR"
        case failed = "FAILED"
        case pendingAcceptance = "PENDING_ACCEPTANCE"
        case ready = "READY"
        case rejected = "REJECTED"
        case rejecting = "REJECTING"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct AZSyncState: AWSDecodableShape {
        public let attachment: Attachment?

        @inlinable
        public init(attachment: Attachment? = nil) {
            self.attachment = attachment
        }

        private enum CodingKeys: String, CodingKey {
            case attachment = "Attachment"
        }
    }

    public struct AcceptNetworkFirewallTransitGatewayAttachmentRequest: AWSEncodableShape {
        /// Required. The unique identifier of the transit gateway attachment to accept. This ID is returned in the response when creating a transit gateway-attached firewall.
        public let transitGatewayAttachmentId: String

        @inlinable
        public init(transitGatewayAttachmentId: String) {
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
        }

        public func validate(name: String) throws {
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, max: 128)
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, min: 1)
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, pattern: "^tgw-attach-[0-9a-z]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
        }
    }

    public struct AcceptNetworkFirewallTransitGatewayAttachmentResponse: AWSDecodableShape {
        /// The unique identifier of the transit gateway attachment that was accepted.
        public let transitGatewayAttachmentId: String
        /// The current status of the transit gateway attachment. Valid values are:    CREATING - The attachment is being created    DELETING - The attachment is being deleted    DELETED - The attachment has been deleted    FAILED - The attachment creation has failed and cannot be recovered    ERROR - The attachment is in an error state that might be recoverable    READY - The attachment is active and processing traffic    PENDING_ACCEPTANCE - The attachment is waiting to be accepted    REJECTING - The attachment is in the process of being rejected    REJECTED - The attachment has been rejected
        public let transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus

        @inlinable
        public init(transitGatewayAttachmentId: String, transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus) {
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
            self.transitGatewayAttachmentStatus = transitGatewayAttachmentStatus
        }

        private enum CodingKeys: String, CodingKey {
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
            case transitGatewayAttachmentStatus = "TransitGatewayAttachmentStatus"
        }
    }

    public struct ActionDefinition: AWSEncodableShape & AWSDecodableShape {
        /// Stateless inspection criteria that publishes the specified metrics to Amazon CloudWatch for the matching packet. This setting defines a CloudWatch dimension value to be published. You can pair this custom action with any of the standard stateless rule actions. For example, you could pair this in a rule action with the standard action that forwards the packet for stateful inspection. Then, when a packet matches the rule, Network Firewall publishes metrics for the packet and forwards it.
        public let publishMetricAction: PublishMetricAction?

        @inlinable
        public init(publishMetricAction: PublishMetricAction? = nil) {
            self.publishMetricAction = publishMetricAction
        }

        public func validate(name: String) throws {
            try self.publishMetricAction?.validate(name: "\(name).publishMetricAction")
        }

        private enum CodingKeys: String, CodingKey {
            case publishMetricAction = "PublishMetricAction"
        }
    }

    public struct Address: AWSEncodableShape & AWSDecodableShape {
        /// Specify an IP address or a block of IP addresses in Classless Inter-Domain Routing (CIDR) notation. Network Firewall supports all address ranges for IPv4 and IPv6.  Examples:    To configure Network Firewall to inspect for the IP address 192.0.2.44, specify 192.0.2.44/32.   To configure Network Firewall to inspect for IP addresses from 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24.   To configure Network Firewall to inspect for the IP address 1111:0000:0000:0000:0000:0000:0000:0111, specify 1111:0000:0000:0000:0000:0000:0000:0111/128.   To configure Network Firewall to inspect for IP addresses from 1111:0000:0000:0000:0000:0000:0000:0000 to 1111:0000:0000:0000:ffff:ffff:ffff:ffff, specify 1111:0000:0000:0000:0000:0000:0000:0000/64.   For more information about CIDR notation, see the Wikipedia entry Classless Inter-Domain Routing.
        public let addressDefinition: String

        @inlinable
        public init(addressDefinition: String) {
            self.addressDefinition = addressDefinition
        }

        public func validate(name: String) throws {
            try self.validate(self.addressDefinition, name: "addressDefinition", parent: name, max: 255)
            try self.validate(self.addressDefinition, name: "addressDefinition", parent: name, min: 1)
            try self.validate(self.addressDefinition, name: "addressDefinition", parent: name, pattern: "^([a-fA-F\\d:\\.]+($|/\\d{1,3}))$")
        }

        private enum CodingKeys: String, CodingKey {
            case addressDefinition = "AddressDefinition"
        }
    }

    public struct AnalysisReport: AWSDecodableShape {
        /// The unique ID of the query that ran when you requested an analysis report.
        public let analysisReportId: String?
        /// The type of traffic that will be used to generate a report.
        public let analysisType: EnabledAnalysisType?
        /// The date and time the analysis report was ran.
        public let reportTime: Date?
        /// The status of the analysis report you specify. Statuses include RUNNING, COMPLETED, or FAILED.
        public let status: String?

        @inlinable
        public init(analysisReportId: String? = nil, analysisType: EnabledAnalysisType? = nil, reportTime: Date? = nil, status: String? = nil) {
            self.analysisReportId = analysisReportId
            self.analysisType = analysisType
            self.reportTime = reportTime
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case analysisReportId = "AnalysisReportId"
            case analysisType = "AnalysisType"
            case reportTime = "ReportTime"
            case status = "Status"
        }
    }

    public struct AnalysisResult: AWSDecodableShape {
        /// Provides analysis details for the identified rule.
        public let analysisDetail: String?
        /// The priority number of the stateless rules identified in the analysis.
        public let identifiedRuleIds: [String]?
        /// The types of rule configurations that Network Firewall analyzes your rule groups for. Network Firewall analyzes stateless rule groups for the following types of rule configurations:    STATELESS_RULE_FORWARDING_ASYMMETRICALLY  Cause: One or more stateless rules with the action pass or forward are forwarding traffic asymmetrically. Specifically, the rule's set of source IP addresses  or their associated port numbers, don't match the set of destination IP addresses or their associated port numbers. To mitigate: Make sure that there's an existing return path. For example, if the rule allows traffic from source 10.1.0.0/24 to destination 20.1.0.0/24, you should allow return traffic from source 20.1.0.0/24 to destination 10.1.0.0/24.    STATELESS_RULE_CONTAINS_TCP_FLAGS  Cause: At least one stateless rule with the action pass orforward contains TCP flags that are inconsistent in the forward and return directions. To mitigate: Prevent asymmetric routing issues caused by TCP flags by following these actions:   Remove unnecessary TCP flag inspections from the rules.   If you need to inspect TCP flags, check that the rules correctly account for changes in TCP flags throughout the TCP connection cycle, for example SYN and ACK flags used in a 3-way TCP handshake.
        public let identifiedType: IdentifiedType?

        @inlinable
        public init(analysisDetail: String? = nil, identifiedRuleIds: [String]? = nil, identifiedType: IdentifiedType? = nil) {
            self.analysisDetail = analysisDetail
            self.identifiedRuleIds = identifiedRuleIds
            self.identifiedType = identifiedType
        }

        private enum CodingKeys: String, CodingKey {
            case analysisDetail = "AnalysisDetail"
            case identifiedRuleIds = "IdentifiedRuleIds"
            case identifiedType = "IdentifiedType"
        }
    }

    public struct AnalysisTypeReportResult: AWSDecodableShape {
        /// The most frequently accessed domains.
        public let domain: String?
        /// The date and time any domain was first accessed (within the last 30 day period).
        public let firstAccessed: Date?
        /// The number of attempts made to access a observed domain.
        public let hits: Hits?
        /// The date and time any domain was last accessed (within the last 30 day period).
        public let lastAccessed: Date?
        /// The type of traffic captured by the analysis report.
        public let `protocol`: String?
        /// The number of unique source IP addresses that connected to a domain.
        public let uniqueSources: UniqueSources?

        @inlinable
        public init(domain: String? = nil, firstAccessed: Date? = nil, hits: Hits? = nil, lastAccessed: Date? = nil, protocol: String? = nil, uniqueSources: UniqueSources? = nil) {
            self.domain = domain
            self.firstAccessed = firstAccessed
            self.hits = hits
            self.lastAccessed = lastAccessed
            self.`protocol` = `protocol`
            self.uniqueSources = uniqueSources
        }

        private enum CodingKeys: String, CodingKey {
            case domain = "Domain"
            case firstAccessed = "FirstAccessed"
            case hits = "Hits"
            case lastAccessed = "LastAccessed"
            case `protocol` = "Protocol"
            case uniqueSources = "UniqueSources"
        }
    }

    public struct AssociateAvailabilityZonesRequest: AWSEncodableShape {
        /// Required. The Availability Zones where you want to create firewall endpoints. You must specify at least one Availability Zone.
        public let availabilityZoneMappings: [AvailabilityZoneMapping]
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(availabilityZoneMappings: [AvailabilityZoneMapping], firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.availabilityZoneMappings = availabilityZoneMappings
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.availabilityZoneMappings.forEach {
                try $0.validate(name: "\(name).availabilityZoneMappings[]")
            }
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneMappings = "AvailabilityZoneMappings"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateAvailabilityZonesResponse: AWSDecodableShape {
        /// The Availability Zones where Network Firewall created firewall endpoints. Each mapping specifies an Availability Zone where the firewall processes traffic.
        public let availabilityZoneMappings: [AvailabilityZoneMapping]?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(availabilityZoneMappings: [AvailabilityZoneMapping]? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.availabilityZoneMappings = availabilityZoneMappings
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneMappings = "AvailabilityZoneMappings"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateFirewallPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let firewallPolicyArn: String
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyArn: String, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateFirewallPolicyResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let firewallPolicyArn: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyArn: String? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateSubnetsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The IDs of the subnets that you want to associate with the firewall.
        public let subnetMappings: [SubnetMapping]
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetMappings: [SubnetMapping], updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetMappings = subnetMappings
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetMappings = "SubnetMappings"
            case updateToken = "UpdateToken"
        }
    }

    public struct AssociateSubnetsResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The IDs of the subnets that are associated with the firewall.
        public let subnetMappings: [SubnetMapping]?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetMappings: [SubnetMapping]? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetMappings = subnetMappings
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetMappings = "SubnetMappings"
            case updateToken = "UpdateToken"
        }
    }

    public struct Attachment: AWSDecodableShape {
        /// The identifier of the firewall endpoint that Network Firewall has instantiated in the subnet. You use this to identify the firewall endpoint in the VPC route tables, when you redirect the VPC traffic through the endpoint.
        public let endpointId: String?
        /// The current status of the firewall endpoint instantiation in the subnet.  When this value is READY, the endpoint is available to handle network traffic. Otherwise, this value reflects its state, for example CREATING or DELETING.
        public let status: AttachmentStatus?
        /// If Network Firewall fails to create or delete the firewall endpoint in the subnet, it populates this with the reason for the error or failure and how to resolve it.  A FAILED status indicates a non-recoverable state, and a ERROR status indicates an issue that you can fix.  Depending on the error, it can take as many as 15 minutes to populate this field. For more information about the causes for failiure or errors and solutions available for this field, see Troubleshooting firewall endpoint failures in the Network Firewall Developer Guide.
        public let statusMessage: String?
        /// The unique identifier of the subnet that you've specified to be used for a firewall endpoint.
        public let subnetId: String?

        @inlinable
        public init(endpointId: String? = nil, status: AttachmentStatus? = nil, statusMessage: String? = nil, subnetId: String? = nil) {
            self.endpointId = endpointId
            self.status = status
            self.statusMessage = statusMessage
            self.subnetId = subnetId
        }

        private enum CodingKeys: String, CodingKey {
            case endpointId = "EndpointId"
            case status = "Status"
            case statusMessage = "StatusMessage"
            case subnetId = "SubnetId"
        }
    }

    public struct AvailabilityZoneMapping: AWSEncodableShape & AWSDecodableShape {
        /// The ID of the Availability Zone where the firewall endpoint is located. For example, us-east-2a. The Availability Zone must be in the same Region as the transit gateway.
        public let availabilityZone: String

        @inlinable
        public init(availabilityZone: String) {
            self.availabilityZone = availabilityZone
        }

        public func validate(name: String) throws {
            try self.validate(self.availabilityZone, name: "availabilityZone", parent: name, max: 128)
            try self.validate(self.availabilityZone, name: "availabilityZone", parent: name, min: 1)
            try self.validate(self.availabilityZone, name: "availabilityZone", parent: name, pattern: "^\\S+$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
        }
    }

    public struct AvailabilityZoneMetadata: AWSDecodableShape {
        /// The IP address type of the Firewall subnet in the Availability Zone. You can't change the IP address type after you create the subnet.
        public let ipAddressType: IPAddressType?

        @inlinable
        public init(ipAddressType: IPAddressType? = nil) {
            self.ipAddressType = ipAddressType
        }

        private enum CodingKeys: String, CodingKey {
            case ipAddressType = "IPAddressType"
        }
    }

    public struct CIDRSummary: AWSDecodableShape {
        /// The number of CIDR blocks available for use by the IP set references in a firewall.
        public let availableCIDRCount: Int?
        /// The list of the IP set references used by a firewall.
        public let ipSetReferences: [String: IPSetMetadata]?
        /// The number of CIDR blocks used by the IP set references in a firewall.
        public let utilizedCIDRCount: Int?

        @inlinable
        public init(availableCIDRCount: Int? = nil, ipSetReferences: [String: IPSetMetadata]? = nil, utilizedCIDRCount: Int? = nil) {
            self.availableCIDRCount = availableCIDRCount
            self.ipSetReferences = ipSetReferences
            self.utilizedCIDRCount = utilizedCIDRCount
        }

        private enum CodingKeys: String, CodingKey {
            case availableCIDRCount = "AvailableCIDRCount"
            case ipSetReferences = "IPSetReferences"
            case utilizedCIDRCount = "UtilizedCIDRCount"
        }
    }

    public struct CapacityUsageSummary: AWSDecodableShape {
        /// Describes the capacity usage of the CIDR blocks used by the IP set references in a firewall.
        public let cidRs: CIDRSummary?

        @inlinable
        public init(cidRs: CIDRSummary? = nil) {
            self.cidRs = cidRs
        }

        private enum CodingKeys: String, CodingKey {
            case cidRs = "CIDRs"
        }
    }

    public struct CheckCertificateRevocationStatusActions: AWSEncodableShape & AWSDecodableShape {
        /// Configures how Network Firewall processes traffic when it determines that the certificate presented by the server in the SSL/TLS connection has a revoked status.    PASS - Allow the connection to continue, and pass subsequent packets to the stateful engine for inspection.    DROP - Network Firewall closes the connection and drops subsequent packets for that connection.    REJECT - Network Firewall sends a TCP reject packet back to your client. The service closes the connection and drops subsequent packets for that connection. REJECT is available only for TCP traffic.
        public let revokedStatusAction: RevocationCheckAction?
        /// Configures how Network Firewall processes traffic when it determines that the certificate presented by the server in the SSL/TLS connection has an unknown status, or a status that cannot be determined for any other reason, including when the service is unable to connect to the OCSP and CRL endpoints for the certificate.    PASS - Allow the connection to continue, and pass subsequent packets to the stateful engine for inspection.    DROP - Network Firewall closes the connection and drops subsequent packets for that connection.    REJECT - Network Firewall sends a TCP reject packet back to your client. The service closes the connection and drops subsequent packets for that connection. REJECT is available only for TCP traffic.
        public let unknownStatusAction: RevocationCheckAction?

        @inlinable
        public init(revokedStatusAction: RevocationCheckAction? = nil, unknownStatusAction: RevocationCheckAction? = nil) {
            self.revokedStatusAction = revokedStatusAction
            self.unknownStatusAction = unknownStatusAction
        }

        private enum CodingKeys: String, CodingKey {
            case revokedStatusAction = "RevokedStatusAction"
            case unknownStatusAction = "UnknownStatusAction"
        }
    }

    public struct CreateFirewallPolicyRequest: AWSEncodableShape {
        /// A description of the firewall policy.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// A complex type that contains settings for encryption of your firewall policy resources.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The rule groups and policy actions to use in the firewall policy.
        public let firewallPolicy: FirewallPolicy
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it.
        public let firewallPolicyName: String
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?

        @inlinable
        public init(description: String? = nil, dryRun: Bool? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, firewallPolicy: FirewallPolicy, firewallPolicyName: String, tags: [Tag]? = nil) {
            self.description = description
            self.dryRun = dryRun
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallPolicy = firewallPolicy
            self.firewallPolicyName = firewallPolicyName
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.firewallPolicy.validate(name: "\(name).firewallPolicy")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case dryRun = "DryRun"
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallPolicy = "FirewallPolicy"
            case firewallPolicyName = "FirewallPolicyName"
            case tags = "Tags"
        }
    }

    public struct CreateFirewallPolicyResponse: AWSDecodableShape {
        /// The high-level properties of a firewall policy. This, along with the FirewallPolicy, define the policy. You can retrieve all objects for a firewall policy by calling DescribeFirewallPolicy.
        public let firewallPolicyResponse: FirewallPolicyResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(firewallPolicyResponse: FirewallPolicyResponse, updateToken: String) {
            self.firewallPolicyResponse = firewallPolicyResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyResponse = "FirewallPolicyResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct CreateFirewallRequest: AWSEncodableShape {
        /// Optional. A setting indicating whether the firewall is protected against changes to its Availability Zone configuration. When set to TRUE, you cannot add or remove Availability Zones without first disabling this protection using UpdateAvailabilityZoneChangeProtection. Default value: FALSE
        public let availabilityZoneChangeProtection: Bool?
        /// Required. The Availability Zones where you want to create firewall endpoints for a transit gateway-attached firewall. You must specify at least one Availability Zone. Consider enabling the firewall in every Availability Zone where you have workloads to maintain Availability Zone isolation. You can modify Availability Zones later using AssociateAvailabilityZones or DisassociateAvailabilityZones, but this may briefly disrupt traffic. The AvailabilityZoneChangeProtection setting controls whether you can make these modifications.
        public let availabilityZoneMappings: [AvailabilityZoneMapping]?
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool?
        /// A description of the firewall.
        public let description: String?
        /// An optional setting indicating the specific traffic analysis types to enable on the firewall.
        public let enabledAnalysisTypes: [EnabledAnalysisType]?
        /// A complex type that contains settings for encryption of your firewall resources.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String
        /// The Amazon Resource Name (ARN) of the FirewallPolicy that you want to use for the firewall.
        public let firewallPolicyArn: String
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool?
        /// The public subnets to use for your Network Firewall firewalls. Each subnet must belong to a different Availability Zone in the VPC. Network Firewall creates a firewall endpoint in each subnet.
        public let subnetMappings: [SubnetMapping]?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// Required when creating a transit gateway-attached firewall. The unique identifier of the transit gateway to attach to this firewall. You can provide either a transit gateway from your account or one that has been shared with you through Resource Access Manager.  After creating the firewall, you cannot change the transit gateway association. To use a different transit gateway, you must create a new firewall.  For information about creating firewalls, see CreateFirewall. For specific guidance about transit gateway-attached firewalls, see Considerations for transit gateway-attached firewalls in the Network Firewall Developer Guide.
        public let transitGatewayId: String?
        /// The unique identifier of the VPC where Network Firewall should create the firewall.  You can't change this setting after you create the firewall.
        public let vpcId: String?

        @inlinable
        public init(availabilityZoneChangeProtection: Bool? = nil, availabilityZoneMappings: [AvailabilityZoneMapping]? = nil, deleteProtection: Bool? = nil, description: String? = nil, enabledAnalysisTypes: [EnabledAnalysisType]? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, firewallName: String, firewallPolicyArn: String, firewallPolicyChangeProtection: Bool? = nil, subnetChangeProtection: Bool? = nil, subnetMappings: [SubnetMapping]? = nil, tags: [Tag]? = nil, transitGatewayId: String? = nil, vpcId: String? = nil) {
            self.availabilityZoneChangeProtection = availabilityZoneChangeProtection
            self.availabilityZoneMappings = availabilityZoneMappings
            self.deleteProtection = deleteProtection
            self.description = description
            self.enabledAnalysisTypes = enabledAnalysisTypes
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.subnetChangeProtection = subnetChangeProtection
            self.subnetMappings = subnetMappings
            self.tags = tags
            self.transitGatewayId = transitGatewayId
            self.vpcId = vpcId
        }

        public func validate(name: String) throws {
            try self.availabilityZoneMappings?.forEach {
                try $0.validate(name: "\(name).availabilityZoneMappings[]")
            }
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.validate(self.transitGatewayId, name: "transitGatewayId", parent: name, max: 128)
            try self.validate(self.transitGatewayId, name: "transitGatewayId", parent: name, min: 1)
            try self.validate(self.transitGatewayId, name: "transitGatewayId", parent: name, pattern: "^tgw-[0-9a-z]+$")
            try self.validate(self.vpcId, name: "vpcId", parent: name, max: 128)
            try self.validate(self.vpcId, name: "vpcId", parent: name, min: 1)
            try self.validate(self.vpcId, name: "vpcId", parent: name, pattern: "^vpc-[0-9a-f]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneChangeProtection = "AvailabilityZoneChangeProtection"
            case availabilityZoneMappings = "AvailabilityZoneMappings"
            case deleteProtection = "DeleteProtection"
            case description = "Description"
            case enabledAnalysisTypes = "EnabledAnalysisTypes"
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case subnetChangeProtection = "SubnetChangeProtection"
            case subnetMappings = "SubnetMappings"
            case tags = "Tags"
            case transitGatewayId = "TransitGatewayId"
            case vpcId = "VpcId"
        }
    }

    public struct CreateFirewallResponse: AWSDecodableShape {
        /// The configuration settings for the firewall. These settings include the firewall policy and the subnets in your VPC to use for the firewall endpoints.
        public let firewall: Firewall?
        /// Detailed information about the current status of a Firewall. You can retrieve this for a firewall by calling DescribeFirewall and providing the firewall name and ARN. The firewall status indicates a combined status. It indicates whether all subnets are up-to-date with the latest firewall configurations, which is based on the sync states config values, and also whether all subnets have their endpoints fully enabled, based on their sync states attachment values.
        public let firewallStatus: FirewallStatus?

        @inlinable
        public init(firewall: Firewall? = nil, firewallStatus: FirewallStatus? = nil) {
            self.firewall = firewall
            self.firewallStatus = firewallStatus
        }

        private enum CodingKeys: String, CodingKey {
            case firewall = "Firewall"
            case firewallStatus = "FirewallStatus"
        }
    }

    public struct CreateRuleGroupRequest: AWSEncodableShape {
        /// Indicates whether you want Network Firewall to analyze the stateless rules in the rule group for rule behavior such as asymmetric routing. If set to TRUE, Network Firewall runs the analysis and then creates the rule group for you. To run the stateless rule group analyzer without creating the rule group, set DryRun to TRUE.
        public let analyzeRuleGroup: Bool?
        /// The maximum operating resources that this rule group can use. Rule group capacity is fixed at creation. When you update a rule group, you are limited to this capacity. When you reference a rule group from a firewall policy, Network Firewall reserves this capacity for the rule group.  You can retrieve the capacity that would be required for a rule group before you create the rule group by calling CreateRuleGroup with DryRun set to TRUE.   You can't change or exceed this capacity when you update the rule group, so leave room for your rule group to grow.    Capacity for a stateless rule group  For a stateless rule group, the capacity required is the sum of the capacity requirements of the individual rules that you expect to have in the rule group.  To calculate the capacity requirement of a single rule, multiply the capacity requirement values of each of the rule's match settings:   A match setting with no criteria specified has a value of 1.    A match setting with Any specified has a value of 1.    All other match settings have a value equal to the number of elements provided in the setting. For example, a protocol setting ["UDP"] and a source setting ["10.0.0.0/24"] each have a value of 1. A protocol setting ["UDP","TCP"] has a value of 2. A source setting ["10.0.0.0/24","10.0.0.1/24","10.0.0.2/24"] has a value of 3.    A rule with no criteria specified in any of its match settings has a capacity requirement of 1. A rule with protocol setting ["UDP","TCP"], source setting ["10.0.0.0/24","10.0.0.1/24","10.0.0.2/24"], and a single specification or no specification for each of the other match settings has a capacity requirement of 6.   Capacity for a stateful rule group  For a stateful rule group, the minimum capacity required is the number of individual rules that you expect to have in the rule group.
        public let capacity: Int
        /// A description of the rule group.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// A complex type that contains settings for encryption of your rule group resources.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// An object that defines the rule group rules.   You must provide either this rule group setting or a Rules setting, but not both.
        public let ruleGroup: RuleGroup?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let ruleGroupName: String
        /// A string containing stateful rule group rules specifications in Suricata flat format, with one rule
        /// per line. Use this to import your existing Suricata compatible rule groups.   You must provide either this rules setting or a populated RuleGroup setting, but not both.   You can provide your rule group specification in Suricata flat format through this setting when you create or update your rule group. The call
        /// response returns a RuleGroup object that Network Firewall has populated from your string.
        public let rules: String?
        /// A complex type that contains metadata about the rule group that your own rule group is copied from. You can use the metadata to keep track of updates made to the originating rule group.
        public let sourceMetadata: SourceMetadata?
        /// An object that contains a RuleOptions array of strings.  You use RuleOptions to determine which of the following RuleSummary values are returned in response to DescribeRuleGroupSummary.    Metadata - returns    Msg     SID
        public let summaryConfiguration: SummaryConfiguration?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.
        public let type: RuleGroupType

        @inlinable
        public init(analyzeRuleGroup: Bool? = nil, capacity: Int, description: String? = nil, dryRun: Bool? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, ruleGroup: RuleGroup? = nil, ruleGroupName: String, rules: String? = nil, sourceMetadata: SourceMetadata? = nil, summaryConfiguration: SummaryConfiguration? = nil, tags: [Tag]? = nil, type: RuleGroupType) {
            self.analyzeRuleGroup = analyzeRuleGroup
            self.capacity = capacity
            self.description = description
            self.dryRun = dryRun
            self.encryptionConfiguration = encryptionConfiguration
            self.ruleGroup = ruleGroup
            self.ruleGroupName = ruleGroupName
            self.rules = rules
            self.sourceMetadata = sourceMetadata
            self.summaryConfiguration = summaryConfiguration
            self.tags = tags
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.ruleGroup?.validate(name: "\(name).ruleGroup")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.rules, name: "rules", parent: name, max: 2000000)
            try self.sourceMetadata?.validate(name: "\(name).sourceMetadata")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case analyzeRuleGroup = "AnalyzeRuleGroup"
            case capacity = "Capacity"
            case description = "Description"
            case dryRun = "DryRun"
            case encryptionConfiguration = "EncryptionConfiguration"
            case ruleGroup = "RuleGroup"
            case ruleGroupName = "RuleGroupName"
            case rules = "Rules"
            case sourceMetadata = "SourceMetadata"
            case summaryConfiguration = "SummaryConfiguration"
            case tags = "Tags"
            case type = "Type"
        }
    }

    public struct CreateRuleGroupResponse: AWSDecodableShape {
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(ruleGroupResponse: RuleGroupResponse, updateToken: String) {
            self.ruleGroupResponse = ruleGroupResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupResponse = "RuleGroupResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct CreateTLSInspectionConfigurationRequest: AWSEncodableShape {
        /// A description of the TLS inspection configuration.
        public let description: String?
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// The object that defines a TLS inspection configuration. This, along with TLSInspectionConfigurationResponse, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.  Network Firewall uses a TLS inspection configuration to decrypt traffic. Network Firewall re-encrypts the traffic before sending it to its destination. To use a TLS inspection configuration, you add it to a new Network Firewall firewall policy, then you apply the firewall policy to a firewall. Network Firewall acts as a proxy service to decrypt and inspect the traffic traveling through your firewalls. You can reference a TLS inspection configuration from more than one firewall policy, and you can use a firewall policy in more than one firewall. For more information about using TLS inspection configurations, see  Inspecting SSL/TLS traffic with TLS
        /// inspection configurations in the Network Firewall Developer Guide.
        public let tlsInspectionConfiguration: TLSInspectionConfiguration
        /// The descriptive name of the TLS inspection configuration. You can't change the name of a TLS inspection configuration after you create it.
        public let tlsInspectionConfigurationName: String

        @inlinable
        public init(description: String? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, tags: [Tag]? = nil, tlsInspectionConfiguration: TLSInspectionConfiguration, tlsInspectionConfigurationName: String) {
            self.description = description
            self.encryptionConfiguration = encryptionConfiguration
            self.tags = tags
            self.tlsInspectionConfiguration = tlsInspectionConfiguration
            self.tlsInspectionConfigurationName = tlsInspectionConfigurationName
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.tlsInspectionConfiguration.validate(name: "\(name).tlsInspectionConfiguration")
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, max: 128)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case encryptionConfiguration = "EncryptionConfiguration"
            case tags = "Tags"
            case tlsInspectionConfiguration = "TLSInspectionConfiguration"
            case tlsInspectionConfigurationName = "TLSInspectionConfigurationName"
        }
    }

    public struct CreateTLSInspectionConfigurationResponse: AWSDecodableShape {
        /// The high-level properties of a TLS inspection configuration. This, along with the TLSInspectionConfiguration, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.
        public let tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the TLS inspection configuration. The token marks the state of the TLS inspection configuration resource at the time of the request.  To make changes to the TLS inspection configuration, you provide the token in your request. Network Firewall uses the token to ensure that the TLS inspection configuration hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the TLS inspection configuration again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse, updateToken: String) {
            self.tlsInspectionConfigurationResponse = tlsInspectionConfigurationResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case tlsInspectionConfigurationResponse = "TLSInspectionConfigurationResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct CreateVpcEndpointAssociationRequest: AWSEncodableShape {
        /// A description of the VPC endpoint association.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        public let subnetMapping: SubnetMapping
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// The unique identifier of the VPC where you want to create a firewall endpoint.
        public let vpcId: String

        @inlinable
        public init(description: String? = nil, firewallArn: String, subnetMapping: SubnetMapping, tags: [Tag]? = nil, vpcId: String) {
            self.description = description
            self.firewallArn = firewallArn
            self.subnetMapping = subnetMapping
            self.tags = tags
            self.vpcId = vpcId
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.tags?.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
            try self.validate(self.vpcId, name: "vpcId", parent: name, max: 128)
            try self.validate(self.vpcId, name: "vpcId", parent: name, min: 1)
            try self.validate(self.vpcId, name: "vpcId", parent: name, pattern: "^vpc-[0-9a-f]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case subnetMapping = "SubnetMapping"
            case tags = "Tags"
            case vpcId = "VpcId"
        }
    }

    public struct CreateVpcEndpointAssociationResponse: AWSDecodableShape {
        /// The configuration settings for the VPC endpoint association. These settings include the firewall and the VPC and subnet to use for the firewall endpoint.
        public let vpcEndpointAssociation: VpcEndpointAssociation?
        /// Detailed information about the current status of a VpcEndpointAssociation. You can retrieve this
        /// by calling DescribeVpcEndpointAssociation and providing the VPC endpoint association ARN.
        public let vpcEndpointAssociationStatus: VpcEndpointAssociationStatus?

        @inlinable
        public init(vpcEndpointAssociation: VpcEndpointAssociation? = nil, vpcEndpointAssociationStatus: VpcEndpointAssociationStatus? = nil) {
            self.vpcEndpointAssociation = vpcEndpointAssociation
            self.vpcEndpointAssociationStatus = vpcEndpointAssociationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case vpcEndpointAssociation = "VpcEndpointAssociation"
            case vpcEndpointAssociationStatus = "VpcEndpointAssociationStatus"
        }
    }

    public struct CustomAction: AWSEncodableShape & AWSDecodableShape {
        /// The custom action associated with the action name.
        public let actionDefinition: ActionDefinition
        /// The descriptive name of the custom action. You can't change the name of a custom action after you create it.
        public let actionName: String

        @inlinable
        public init(actionDefinition: ActionDefinition, actionName: String) {
            self.actionDefinition = actionDefinition
            self.actionName = actionName
        }

        public func validate(name: String) throws {
            try self.actionDefinition.validate(name: "\(name).actionDefinition")
            try self.validate(self.actionName, name: "actionName", parent: name, max: 128)
            try self.validate(self.actionName, name: "actionName", parent: name, min: 1)
            try self.validate(self.actionName, name: "actionName", parent: name, pattern: "^[a-zA-Z0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case actionDefinition = "ActionDefinition"
            case actionName = "ActionName"
        }
    }

    public struct DeleteFirewallPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall policy. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyArn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyName: String?

        @inlinable
        public init(firewallPolicyArn: String? = nil, firewallPolicyName: String? = nil) {
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyName = firewallPolicyName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyName = "FirewallPolicyName"
        }
    }

    public struct DeleteFirewallPolicyResponse: AWSDecodableShape {
        /// The object containing the definition of the FirewallPolicyResponse that you asked to delete.
        public let firewallPolicyResponse: FirewallPolicyResponse

        @inlinable
        public init(firewallPolicyResponse: FirewallPolicyResponse) {
            self.firewallPolicyResponse = firewallPolicyResponse
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyResponse = "FirewallPolicyResponse"
        }
    }

    public struct DeleteFirewallRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct DeleteFirewallResponse: AWSDecodableShape {
        public let firewall: Firewall?
        public let firewallStatus: FirewallStatus?

        @inlinable
        public init(firewall: Firewall? = nil, firewallStatus: FirewallStatus? = nil) {
            self.firewall = firewall
            self.firewallStatus = firewallStatus
        }

        private enum CodingKeys: String, CodingKey {
            case firewall = "Firewall"
            case firewallStatus = "FirewallStatus"
        }
    }

    public struct DeleteNetworkFirewallTransitGatewayAttachmentRequest: AWSEncodableShape {
        /// Required. The unique identifier of the transit gateway attachment to delete.
        public let transitGatewayAttachmentId: String

        @inlinable
        public init(transitGatewayAttachmentId: String) {
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
        }

        public func validate(name: String) throws {
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, max: 128)
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, min: 1)
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, pattern: "^tgw-attach-[0-9a-z]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
        }
    }

    public struct DeleteNetworkFirewallTransitGatewayAttachmentResponse: AWSDecodableShape {
        /// The ID of the transit gateway attachment that was deleted.
        public let transitGatewayAttachmentId: String
        /// The current status of the transit gateway attachment deletion process. Valid values are:    CREATING - The attachment is being created    DELETING - The attachment is being deleted    DELETED - The attachment has been deleted    FAILED - The attachment creation has failed and cannot be recovered    ERROR - The attachment is in an error state that might be recoverable    READY - The attachment is active and processing traffic    PENDING_ACCEPTANCE - The attachment is waiting to be accepted    REJECTING - The attachment is in the process of being rejected    REJECTED - The attachment has been rejected
        public let transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus

        @inlinable
        public init(transitGatewayAttachmentId: String, transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus) {
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
            self.transitGatewayAttachmentStatus = transitGatewayAttachmentStatus
        }

        private enum CodingKeys: String, CodingKey {
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
            case transitGatewayAttachmentStatus = "TransitGatewayAttachmentStatus"
        }
    }

    public struct DeleteResourcePolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group or firewall policy whose resource policy you want to delete.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct DeleteResourcePolicyResponse: AWSDecodableShape {
        public init() {}
    }

    public struct DeleteRuleGroupRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?

        @inlinable
        public init(ruleGroupArn: String? = nil, ruleGroupName: String? = nil, type: RuleGroupType? = nil) {
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case type = "Type"
        }
    }

    public struct DeleteRuleGroupResponse: AWSDecodableShape {
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse

        @inlinable
        public init(ruleGroupResponse: RuleGroupResponse) {
            self.ruleGroupResponse = ruleGroupResponse
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupResponse = "RuleGroupResponse"
        }
    }

    public struct DeleteTLSInspectionConfigurationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the TLS inspection configuration. You must specify the ARN or the name, and you can specify both.
        public let tlsInspectionConfigurationArn: String?
        /// The descriptive name of the TLS inspection configuration. You can't change the name of a TLS inspection configuration after you create it. You must specify the ARN or the name, and you can specify both.
        public let tlsInspectionConfigurationName: String?

        @inlinable
        public init(tlsInspectionConfigurationArn: String? = nil, tlsInspectionConfigurationName: String? = nil) {
            self.tlsInspectionConfigurationArn = tlsInspectionConfigurationArn
            self.tlsInspectionConfigurationName = tlsInspectionConfigurationName
        }

        public func validate(name: String) throws {
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, max: 256)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, max: 128)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case tlsInspectionConfigurationArn = "TLSInspectionConfigurationArn"
            case tlsInspectionConfigurationName = "TLSInspectionConfigurationName"
        }
    }

    public struct DeleteTLSInspectionConfigurationResponse: AWSDecodableShape {
        /// The high-level properties of a TLS inspection configuration. This, along with the TLSInspectionConfiguration, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.
        public let tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse

        @inlinable
        public init(tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse) {
            self.tlsInspectionConfigurationResponse = tlsInspectionConfigurationResponse
        }

        private enum CodingKeys: String, CodingKey {
            case tlsInspectionConfigurationResponse = "TLSInspectionConfigurationResponse"
        }
    }

    public struct DeleteVpcEndpointAssociationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String

        @inlinable
        public init(vpcEndpointAssociationArn: String) {
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
        }

        public func validate(name: String) throws {
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
        }
    }

    public struct DeleteVpcEndpointAssociationResponse: AWSDecodableShape {
        /// The configuration settings for the VPC endpoint association. These settings include the firewall and the VPC and subnet to use for the firewall endpoint.
        public let vpcEndpointAssociation: VpcEndpointAssociation?
        /// Detailed information about the current status of a VpcEndpointAssociation. You can retrieve this
        /// by calling DescribeVpcEndpointAssociation and providing the VPC endpoint association ARN.
        public let vpcEndpointAssociationStatus: VpcEndpointAssociationStatus?

        @inlinable
        public init(vpcEndpointAssociation: VpcEndpointAssociation? = nil, vpcEndpointAssociationStatus: VpcEndpointAssociationStatus? = nil) {
            self.vpcEndpointAssociation = vpcEndpointAssociation
            self.vpcEndpointAssociationStatus = vpcEndpointAssociationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case vpcEndpointAssociation = "VpcEndpointAssociation"
            case vpcEndpointAssociationStatus = "VpcEndpointAssociationStatus"
        }
    }

    public struct DescribeFirewallMetadataRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?

        @inlinable
        public init(firewallArn: String? = nil) {
            self.firewallArn = firewallArn
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
        }
    }

    public struct DescribeFirewallMetadataResponse: AWSDecodableShape {
        /// A description of the firewall.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let firewallPolicyArn: String?
        /// The readiness of the configured firewall to handle network traffic across all of the Availability Zones where you have it configured. This setting is READY only when the ConfigurationSyncStateSummary value is IN_SYNC and the Attachment Status values for all of the configured subnets are READY.
        public let status: FirewallStatusValue?
        /// The Availability Zones that the firewall currently supports. This includes all Availability Zones for which  the firewall has a subnet defined.
        public let supportedAvailabilityZones: [String: AvailabilityZoneMetadata]?
        /// The unique identifier of the transit gateway attachment associated with this firewall. This field is only present for transit gateway-attached firewalls.
        public let transitGatewayAttachmentId: String?

        @inlinable
        public init(description: String? = nil, firewallArn: String? = nil, firewallPolicyArn: String? = nil, status: FirewallStatusValue? = nil, supportedAvailabilityZones: [String: AvailabilityZoneMetadata]? = nil, transitGatewayAttachmentId: String? = nil) {
            self.description = description
            self.firewallArn = firewallArn
            self.firewallPolicyArn = firewallPolicyArn
            self.status = status
            self.supportedAvailabilityZones = supportedAvailabilityZones
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case firewallPolicyArn = "FirewallPolicyArn"
            case status = "Status"
            case supportedAvailabilityZones = "SupportedAvailabilityZones"
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
        }
    }

    public struct DescribeFirewallPolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall policy. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyArn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyName: String?

        @inlinable
        public init(firewallPolicyArn: String? = nil, firewallPolicyName: String? = nil) {
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyName = firewallPolicyName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyName = "FirewallPolicyName"
        }
    }

    public struct DescribeFirewallPolicyResponse: AWSDecodableShape {
        /// The policy for the specified firewall policy.
        public let firewallPolicy: FirewallPolicy?
        /// The high-level properties of a firewall policy. This, along with the FirewallPolicy, define the policy. You can retrieve all objects for a firewall policy by calling DescribeFirewallPolicy.
        public let firewallPolicyResponse: FirewallPolicyResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(firewallPolicy: FirewallPolicy? = nil, firewallPolicyResponse: FirewallPolicyResponse, updateToken: String) {
            self.firewallPolicy = firewallPolicy
            self.firewallPolicyResponse = firewallPolicyResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicy = "FirewallPolicy"
            case firewallPolicyResponse = "FirewallPolicyResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct DescribeFirewallRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct DescribeFirewallResponse: AWSDecodableShape {
        /// The configuration settings for the firewall. These settings include the firewall policy and the subnets in your VPC to use for the firewall endpoints.
        public let firewall: Firewall?
        /// Detailed information about the current status of a Firewall. You can retrieve this for a firewall by calling DescribeFirewall and providing the firewall name and ARN. The firewall status indicates a combined status. It indicates whether all subnets are up-to-date with the latest firewall configurations, which is based on the sync states config values, and also whether all subnets have their endpoints fully enabled, based on their sync states attachment values.
        public let firewallStatus: FirewallStatus?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewall: Firewall? = nil, firewallStatus: FirewallStatus? = nil, updateToken: String? = nil) {
            self.firewall = firewall
            self.firewallStatus = firewallStatus
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewall = "Firewall"
            case firewallStatus = "FirewallStatus"
            case updateToken = "UpdateToken"
        }
    }

    public struct DescribeFlowOperationRequest: AWSEncodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?
        /// A unique identifier for the primary endpoint associated with a firewall.
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String, flowOperationId: String, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowOperationId = flowOperationId
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.flowOperationId, name: "flowOperationId", parent: name, max: 36)
            try self.validate(self.flowOperationId, name: "flowOperationId", parent: name, min: 36)
            try self.validate(self.flowOperationId, name: "flowOperationId", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, max: 256)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, min: 5)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, pattern: "^vpce-[a-zA-Z0-9]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowOperationId = "FlowOperationId"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct DescribeFlowOperationResponse: AWSDecodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// Returns key information about a flow operation, such as related statuses, unique identifiers, and all filters defined in the operation.
        public let flowOperation: FlowOperation?
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String?
        /// Returns the status of the flow operation. This string is returned in the responses to start, list, and describe commands. If the status is COMPLETED_WITH_ERRORS, results may be returned with any number of Flows missing from the response.
        /// If the status is FAILED, Flows returned will be empty.
        public let flowOperationStatus: FlowOperationStatus?
        /// Defines the type of FlowOperation.
        public let flowOperationType: FlowOperationType?
        /// A timestamp indicating when the Suricata engine identified flows impacted by an operation.
        public let flowRequestTimestamp: Date?
        /// If the asynchronous operation fails, Network Firewall populates this with the reason for the error or failure. Options include Flow operation error and Flow timeout.
        public let statusMessage: String?
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?
        /// A unique identifier for the primary endpoint associated with a firewall.
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String? = nil, flowOperation: FlowOperation? = nil, flowOperationId: String? = nil, flowOperationStatus: FlowOperationStatus? = nil, flowOperationType: FlowOperationType? = nil, flowRequestTimestamp: Date? = nil, statusMessage: String? = nil, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowOperation = flowOperation
            self.flowOperationId = flowOperationId
            self.flowOperationStatus = flowOperationStatus
            self.flowOperationType = flowOperationType
            self.flowRequestTimestamp = flowRequestTimestamp
            self.statusMessage = statusMessage
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowOperation = "FlowOperation"
            case flowOperationId = "FlowOperationId"
            case flowOperationStatus = "FlowOperationStatus"
            case flowOperationType = "FlowOperationType"
            case flowRequestTimestamp = "FlowRequestTimestamp"
            case statusMessage = "StatusMessage"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct DescribeLoggingConfigurationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct DescribeLoggingConfigurationResponse: AWSDecodableShape {
        /// A boolean that reflects whether or not the firewall monitoring dashboard is enabled on a firewall.  Returns TRUE when the firewall monitoring dashboard is enabled on the firewall.  Returns FALSE when the firewall monitoring dashboard is not enabled on the firewall.
        public let enableMonitoringDashboard: Bool?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        public let loggingConfiguration: LoggingConfiguration?

        @inlinable
        public init(enableMonitoringDashboard: Bool? = nil, firewallArn: String? = nil, loggingConfiguration: LoggingConfiguration? = nil) {
            self.enableMonitoringDashboard = enableMonitoringDashboard
            self.firewallArn = firewallArn
            self.loggingConfiguration = loggingConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case enableMonitoringDashboard = "EnableMonitoringDashboard"
            case firewallArn = "FirewallArn"
            case loggingConfiguration = "LoggingConfiguration"
        }
    }

    public struct DescribeResourcePolicyRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the rule group or firewall policy whose resource policy you want to retrieve.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct DescribeResourcePolicyResponse: AWSDecodableShape {
        /// The IAM policy for the resource.
        public let policy: String?

        @inlinable
        public init(policy: String? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
        }
    }

    public struct DescribeRuleGroupMetadataRequest: AWSEncodableShape {
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?

        @inlinable
        public init(ruleGroupArn: String? = nil, ruleGroupName: String? = nil, type: RuleGroupType? = nil) {
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case type = "Type"
        }
    }

    public struct DescribeRuleGroupMetadataResponse: AWSDecodableShape {
        /// The maximum operating resources that this rule group can use. Rule group capacity is fixed at creation. When you update a rule group, you are limited to this capacity. When you reference a rule group from a firewall policy, Network Firewall reserves this capacity for the rule group.  You can retrieve the capacity that would be required for a rule group before you create the rule group by calling CreateRuleGroup with DryRun set to TRUE.
        public let capacity: Int?
        /// Returns the metadata objects for the specified rule group.
        public let description: String?
        /// A timestamp indicating when the rule group was last modified.
        public let lastModifiedTime: Date?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String
        public let statefulRuleOptions: StatefulRuleOptions?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?

        @inlinable
        public init(capacity: Int? = nil, description: String? = nil, lastModifiedTime: Date? = nil, ruleGroupArn: String, ruleGroupName: String, statefulRuleOptions: StatefulRuleOptions? = nil, type: RuleGroupType? = nil) {
            self.capacity = capacity
            self.description = description
            self.lastModifiedTime = lastModifiedTime
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.statefulRuleOptions = statefulRuleOptions
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case capacity = "Capacity"
            case description = "Description"
            case lastModifiedTime = "LastModifiedTime"
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case statefulRuleOptions = "StatefulRuleOptions"
            case type = "Type"
        }
    }

    public struct DescribeRuleGroupRequest: AWSEncodableShape {
        /// Indicates whether you want Network Firewall to analyze the stateless rules in the rule group for rule behavior such as asymmetric routing. If set to TRUE, Network Firewall runs the analysis.
        public let analyzeRuleGroup: Bool?
        /// The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?

        @inlinable
        public init(analyzeRuleGroup: Bool? = nil, ruleGroupArn: String? = nil, ruleGroupName: String? = nil, type: RuleGroupType? = nil) {
            self.analyzeRuleGroup = analyzeRuleGroup
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case analyzeRuleGroup = "AnalyzeRuleGroup"
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case type = "Type"
        }
    }

    public struct DescribeRuleGroupResponse: AWSDecodableShape {
        /// The object that defines the rules in a rule group. This, along with RuleGroupResponse, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.  Network Firewall uses a rule group to inspect and control network traffic. You define stateless rule groups to inspect individual packets and you define stateful rule groups to inspect packets in the context of their traffic flow.  To use a rule group, you include it by reference in an Network Firewall firewall policy, then you use the policy in a firewall. You can reference a rule group from more than one firewall policy, and you can use a firewall policy in more than one firewall.
        public let ruleGroup: RuleGroup?
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(ruleGroup: RuleGroup? = nil, ruleGroupResponse: RuleGroupResponse, updateToken: String) {
            self.ruleGroup = ruleGroup
            self.ruleGroupResponse = ruleGroupResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroup = "RuleGroup"
            case ruleGroupResponse = "RuleGroupResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct DescribeRuleGroupSummaryRequest: AWSEncodableShape {
        /// Required. The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// The type of rule group you want a summary for. This is a required field. Valid value: STATEFUL  Note that STATELESS exists but is not currently supported. If you provide STATELESS, an exception is returned.
        public let type: RuleGroupType?

        @inlinable
        public init(ruleGroupArn: String? = nil, ruleGroupName: String? = nil, type: RuleGroupType? = nil) {
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case type = "Type"
        }
    }

    public struct DescribeRuleGroupSummaryResponse: AWSDecodableShape {
        /// A description of the rule group.
        public let description: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let ruleGroupName: String
        /// A complex type that contains rule information based on the rule group's configured summary settings. The content varies depending on the fields that you specified to extract in your SummaryConfiguration. When you haven't configured any summary settings, this returns an empty array. The response might include:   Rule identifiers   Rule descriptions   Any metadata fields that you specified in your SummaryConfiguration
        public let summary: Summary?

        @inlinable
        public init(description: String? = nil, ruleGroupName: String, summary: Summary? = nil) {
            self.description = description
            self.ruleGroupName = ruleGroupName
            self.summary = summary
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case ruleGroupName = "RuleGroupName"
            case summary = "Summary"
        }
    }

    public struct DescribeTLSInspectionConfigurationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the TLS inspection configuration. You must specify the ARN or the name, and you can specify both.
        public let tlsInspectionConfigurationArn: String?
        /// The descriptive name of the TLS inspection configuration. You can't change the name of a TLS inspection configuration after you create it. You must specify the ARN or the name, and you can specify both.
        public let tlsInspectionConfigurationName: String?

        @inlinable
        public init(tlsInspectionConfigurationArn: String? = nil, tlsInspectionConfigurationName: String? = nil) {
            self.tlsInspectionConfigurationArn = tlsInspectionConfigurationArn
            self.tlsInspectionConfigurationName = tlsInspectionConfigurationName
        }

        public func validate(name: String) throws {
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, max: 256)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, max: 128)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case tlsInspectionConfigurationArn = "TLSInspectionConfigurationArn"
            case tlsInspectionConfigurationName = "TLSInspectionConfigurationName"
        }
    }

    public struct DescribeTLSInspectionConfigurationResponse: AWSDecodableShape {
        /// The object that defines a TLS inspection configuration. This, along with TLSInspectionConfigurationResponse, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.  Network Firewall uses a TLS inspection configuration to decrypt traffic. Network Firewall re-encrypts the traffic before sending it to its destination. To use a TLS inspection configuration, you add it to a new Network Firewall firewall policy, then you apply the firewall policy to a firewall. Network Firewall acts as a proxy service to decrypt and inspect the traffic traveling through your firewalls. You can reference a TLS inspection configuration from more than one firewall policy, and you can use a firewall policy in more than one firewall. For more information about using TLS inspection configurations, see  Inspecting SSL/TLS traffic with TLS
        /// inspection configurations in the Network Firewall Developer Guide.
        public let tlsInspectionConfiguration: TLSInspectionConfiguration?
        /// The high-level properties of a TLS inspection configuration. This, along with the TLSInspectionConfiguration, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.
        public let tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the TLS inspection configuration. The token marks the state of the TLS inspection configuration resource at the time of the request.  To make changes to the TLS inspection configuration, you provide the token in your request. Network Firewall uses the token to ensure that the TLS inspection configuration hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the TLS inspection configuration again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(tlsInspectionConfiguration: TLSInspectionConfiguration? = nil, tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse, updateToken: String) {
            self.tlsInspectionConfiguration = tlsInspectionConfiguration
            self.tlsInspectionConfigurationResponse = tlsInspectionConfigurationResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case tlsInspectionConfiguration = "TLSInspectionConfiguration"
            case tlsInspectionConfigurationResponse = "TLSInspectionConfigurationResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct DescribeVpcEndpointAssociationRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String

        @inlinable
        public init(vpcEndpointAssociationArn: String) {
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
        }

        public func validate(name: String) throws {
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
        }
    }

    public struct DescribeVpcEndpointAssociationResponse: AWSDecodableShape {
        /// The configuration settings for the VPC endpoint association. These settings include the firewall and the VPC and subnet to use for the firewall endpoint.
        public let vpcEndpointAssociation: VpcEndpointAssociation?
        /// Detailed information about the current status of a VpcEndpointAssociation. You can retrieve this
        /// by calling DescribeVpcEndpointAssociation and providing the VPC endpoint association ARN.
        public let vpcEndpointAssociationStatus: VpcEndpointAssociationStatus?

        @inlinable
        public init(vpcEndpointAssociation: VpcEndpointAssociation? = nil, vpcEndpointAssociationStatus: VpcEndpointAssociationStatus? = nil) {
            self.vpcEndpointAssociation = vpcEndpointAssociation
            self.vpcEndpointAssociationStatus = vpcEndpointAssociationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case vpcEndpointAssociation = "VpcEndpointAssociation"
            case vpcEndpointAssociationStatus = "VpcEndpointAssociationStatus"
        }
    }

    public struct Dimension: AWSEncodableShape & AWSDecodableShape {
        /// The value to use in the custom metric dimension.
        public let value: String

        @inlinable
        public init(value: String) {
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.value, name: "value", parent: name, max: 128)
            try self.validate(self.value, name: "value", parent: name, min: 1)
            try self.validate(self.value, name: "value", parent: name, pattern: "^[a-zA-Z0-9-_ ]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case value = "Value"
        }
    }

    public struct DisassociateAvailabilityZonesRequest: AWSEncodableShape {
        /// Required. The Availability Zones to remove from the firewall's configuration.
        public let availabilityZoneMappings: [AvailabilityZoneMapping]
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(availabilityZoneMappings: [AvailabilityZoneMapping], firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.availabilityZoneMappings = availabilityZoneMappings
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.availabilityZoneMappings.forEach {
                try $0.validate(name: "\(name).availabilityZoneMappings[]")
            }
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneMappings = "AvailabilityZoneMappings"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct DisassociateAvailabilityZonesResponse: AWSDecodableShape {
        /// The remaining Availability Zones where the firewall has endpoints after the disassociation.
        public let availabilityZoneMappings: [AvailabilityZoneMapping]?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(availabilityZoneMappings: [AvailabilityZoneMapping]? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.availabilityZoneMappings = availabilityZoneMappings
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneMappings = "AvailabilityZoneMappings"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct DisassociateSubnetsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The unique identifiers for the subnets that you want to disassociate.
        public let subnetIds: [String]
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetIds: [String], updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetIds = subnetIds
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.subnetIds.forEach {
                try validate($0, name: "subnetIds[]", parent: name, max: 128)
                try validate($0, name: "subnetIds[]", parent: name, min: 1)
                try validate($0, name: "subnetIds[]", parent: name, pattern: "^subnet-[0-9a-f]+$")
            }
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetIds = "SubnetIds"
            case updateToken = "UpdateToken"
        }
    }

    public struct DisassociateSubnetsResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The IDs of the subnets that are associated with the firewall.
        public let subnetMappings: [SubnetMapping]?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetMappings: [SubnetMapping]? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetMappings = subnetMappings
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetMappings = "SubnetMappings"
            case updateToken = "UpdateToken"
        }
    }

    public struct EncryptionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The ID of the Amazon Web Services Key Management Service (KMS) customer managed key. You can use any of the key identifiers that KMS supports, unless you're using a key that's managed by another account. If you're using a key managed by another account, then specify the key ARN. For more information, see Key ID in the Amazon Web Services KMS Developer Guide.
        public let keyId: String?
        /// The type of Amazon Web Services KMS key to use for encryption of your Network Firewall resources.
        public let type: EncryptionType

        @inlinable
        public init(keyId: String? = nil, type: EncryptionType) {
            self.keyId = keyId
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.keyId, name: "keyId", parent: name, max: 2048)
            try self.validate(self.keyId, name: "keyId", parent: name, min: 1)
            try self.validate(self.keyId, name: "keyId", parent: name, pattern: "\\S")
        }

        private enum CodingKeys: String, CodingKey {
            case keyId = "KeyId"
            case type = "Type"
        }
    }

    public struct Firewall: AWSDecodableShape {
        /// A setting indicating whether the firewall is protected against changes to its Availability Zone configuration. When set to TRUE, you must first disable this protection before adding or removing Availability Zones.
        public let availabilityZoneChangeProtection: Bool?
        /// The Availability Zones where the firewall endpoints are created for a transit gateway-attached firewall. Each mapping specifies an Availability Zone where the firewall processes traffic.
        public let availabilityZoneMappings: [AvailabilityZoneMapping]?
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool?
        /// A description of the firewall.
        public let description: String?
        /// An optional setting indicating the specific traffic analysis types to enable on the firewall.
        public let enabledAnalysisTypes: [EnabledAnalysisType]?
        /// A complex type that contains the Amazon Web Services KMS encryption configuration settings for your firewall.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The unique identifier for the firewall.
        public let firewallId: String
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The Amazon Resource Name (ARN) of the firewall policy. The relationship of firewall to firewall policy is many to one. Each firewall requires one firewall policy association, and you can use the same firewall policy for multiple firewalls.
        public let firewallPolicyArn: String
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool?
        /// The number of VpcEndpointAssociation resources that use this firewall.
        public let numberOfAssociations: Int?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool?
        /// The primary public subnets that Network Firewall is using for the firewall. Network Firewall creates a firewall endpoint in each subnet. Create a subnet mapping for each Availability Zone where you want to use the firewall. These subnets are all defined for a single, primary VPC, and each must belong to a different Availability Zone. Each of these subnets establishes the availability of the firewall in its Availability Zone.  In addition to these subnets, you can define other endpoints for the firewall in VpcEndpointAssociation resources. You can define these additional endpoints for any VPC, and for any of the Availability Zones where the firewall resource already has a subnet mapping. VPC endpoint associations give you the ability to protect multiple VPCs using a single firewall, and to define multiple firewall endpoints for a VPC in a single Availability Zone.
        public let subnetMappings: [SubnetMapping]
        public let tags: [Tag]?
        /// The unique identifier of the transit gateway associated with this firewall. This field is only present for transit gateway-attached firewalls.
        public let transitGatewayId: String?
        /// The Amazon Web Services account ID that owns the transit gateway. This may be different from the firewall owner's account ID when using a shared transit gateway.
        public let transitGatewayOwnerAccountId: String?
        /// The unique identifier of the VPC where the firewall is in use.
        public let vpcId: String

        @inlinable
        public init(availabilityZoneChangeProtection: Bool? = nil, availabilityZoneMappings: [AvailabilityZoneMapping]? = nil, deleteProtection: Bool? = nil, description: String? = nil, enabledAnalysisTypes: [EnabledAnalysisType]? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, firewallArn: String? = nil, firewallId: String, firewallName: String? = nil, firewallPolicyArn: String, firewallPolicyChangeProtection: Bool? = nil, numberOfAssociations: Int? = nil, subnetChangeProtection: Bool? = nil, subnetMappings: [SubnetMapping], tags: [Tag]? = nil, transitGatewayId: String? = nil, transitGatewayOwnerAccountId: String? = nil, vpcId: String) {
            self.availabilityZoneChangeProtection = availabilityZoneChangeProtection
            self.availabilityZoneMappings = availabilityZoneMappings
            self.deleteProtection = deleteProtection
            self.description = description
            self.enabledAnalysisTypes = enabledAnalysisTypes
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallArn = firewallArn
            self.firewallId = firewallId
            self.firewallName = firewallName
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.numberOfAssociations = numberOfAssociations
            self.subnetChangeProtection = subnetChangeProtection
            self.subnetMappings = subnetMappings
            self.tags = tags
            self.transitGatewayId = transitGatewayId
            self.transitGatewayOwnerAccountId = transitGatewayOwnerAccountId
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneChangeProtection = "AvailabilityZoneChangeProtection"
            case availabilityZoneMappings = "AvailabilityZoneMappings"
            case deleteProtection = "DeleteProtection"
            case description = "Description"
            case enabledAnalysisTypes = "EnabledAnalysisTypes"
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallArn = "FirewallArn"
            case firewallId = "FirewallId"
            case firewallName = "FirewallName"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case numberOfAssociations = "NumberOfAssociations"
            case subnetChangeProtection = "SubnetChangeProtection"
            case subnetMappings = "SubnetMappings"
            case tags = "Tags"
            case transitGatewayId = "TransitGatewayId"
            case transitGatewayOwnerAccountId = "TransitGatewayOwnerAccountId"
            case vpcId = "VpcId"
        }
    }

    public struct FirewallMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// The unique identifier of the transit gateway attachment associated with this firewall. This field is only present for transit gateway-attached firewalls.
        public let transitGatewayAttachmentId: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, transitGatewayAttachmentId: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
        }
    }

    public struct FirewallPolicy: AWSEncodableShape & AWSDecodableShape {
        /// When true, prevents TCP and TLS packets from reaching destination servers until TLS Inspection has evaluated Server Name Indication (SNI) rules. Requires an associated TLS Inspection configuration.
        public let enableTLSSessionHolding: Bool?
        /// Contains variables that you can use to override default Suricata settings in your firewall policy.
        public let policyVariables: PolicyVariables?
        /// The default actions to take on a packet that doesn't match any stateful rules. The stateful default action is optional, and is only valid when using the strict rule order. Valid values of the stateful default action:   aws:drop_strict   aws:drop_established   aws:alert_strict   aws:alert_established   For more information, see Strict evaluation order in the Network Firewall Developer Guide.
        public let statefulDefaultActions: [String]?
        /// Additional options governing how Network Firewall handles stateful rules. The stateful rule groups that you use in your policy must have stateful rule options settings that are compatible with these settings.
        public let statefulEngineOptions: StatefulEngineOptions?
        /// References to the stateful rule groups that are used in the policy. These define the inspection criteria in stateful rules.
        public let statefulRuleGroupReferences: [StatefulRuleGroupReference]?
        /// The custom action definitions that are available for use in the firewall policy's StatelessDefaultActions setting. You name each custom action that you define, and then you can use it by name in your default actions specifications.
        public let statelessCustomActions: [CustomAction]?
        /// The actions to take on a packet if it doesn't match any of the stateless rules in the policy. If you want non-matching packets to be forwarded for stateful inspection, specify aws:forward_to_sfe.  You must specify one of the standard actions: aws:pass, aws:drop, or aws:forward_to_sfe. In addition, you can specify custom actions that are compatible with your standard section choice. For example, you could specify ["aws:pass"] or you could specify ["aws:pass", “customActionName”]. For information about compatibility, see the custom action descriptions under CustomAction.
        public let statelessDefaultActions: [String]
        /// The actions to take on a fragmented UDP packet if it doesn't match any of the stateless rules in the policy. Network Firewall only manages UDP packet fragments and silently drops packet fragments for other protocols. If you want non-matching fragmented UDP packets to be forwarded for stateful inspection, specify aws:forward_to_sfe.  You must specify one of the standard actions: aws:pass, aws:drop, or aws:forward_to_sfe. In addition, you can specify custom actions that are compatible with your standard section choice. For example, you could specify ["aws:pass"] or you could specify ["aws:pass", “customActionName”]. For information about compatibility, see the custom action descriptions under CustomAction.
        public let statelessFragmentDefaultActions: [String]
        /// References to the stateless rule groups that are used in the policy. These define the matching criteria in stateless rules.
        public let statelessRuleGroupReferences: [StatelessRuleGroupReference]?
        /// The Amazon Resource Name (ARN) of the TLS inspection configuration.
        public let tlsInspectionConfigurationArn: String?

        @inlinable
        public init(enableTLSSessionHolding: Bool? = nil, policyVariables: PolicyVariables? = nil, statefulDefaultActions: [String]? = nil, statefulEngineOptions: StatefulEngineOptions? = nil, statefulRuleGroupReferences: [StatefulRuleGroupReference]? = nil, statelessCustomActions: [CustomAction]? = nil, statelessDefaultActions: [String], statelessFragmentDefaultActions: [String], statelessRuleGroupReferences: [StatelessRuleGroupReference]? = nil, tlsInspectionConfigurationArn: String? = nil) {
            self.enableTLSSessionHolding = enableTLSSessionHolding
            self.policyVariables = policyVariables
            self.statefulDefaultActions = statefulDefaultActions
            self.statefulEngineOptions = statefulEngineOptions
            self.statefulRuleGroupReferences = statefulRuleGroupReferences
            self.statelessCustomActions = statelessCustomActions
            self.statelessDefaultActions = statelessDefaultActions
            self.statelessFragmentDefaultActions = statelessFragmentDefaultActions
            self.statelessRuleGroupReferences = statelessRuleGroupReferences
            self.tlsInspectionConfigurationArn = tlsInspectionConfigurationArn
        }

        public func validate(name: String) throws {
            try self.policyVariables?.validate(name: "\(name).policyVariables")
            try self.statefulRuleGroupReferences?.forEach {
                try $0.validate(name: "\(name).statefulRuleGroupReferences[]")
            }
            try self.statelessCustomActions?.forEach {
                try $0.validate(name: "\(name).statelessCustomActions[]")
            }
            try self.statelessRuleGroupReferences?.forEach {
                try $0.validate(name: "\(name).statelessRuleGroupReferences[]")
            }
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, max: 256)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case enableTLSSessionHolding = "EnableTLSSessionHolding"
            case policyVariables = "PolicyVariables"
            case statefulDefaultActions = "StatefulDefaultActions"
            case statefulEngineOptions = "StatefulEngineOptions"
            case statefulRuleGroupReferences = "StatefulRuleGroupReferences"
            case statelessCustomActions = "StatelessCustomActions"
            case statelessDefaultActions = "StatelessDefaultActions"
            case statelessFragmentDefaultActions = "StatelessFragmentDefaultActions"
            case statelessRuleGroupReferences = "StatelessRuleGroupReferences"
            case tlsInspectionConfigurationArn = "TLSInspectionConfigurationArn"
        }
    }

    public struct FirewallPolicyMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall policy.
        public let arn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it.
        public let name: String?

        @inlinable
        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct FirewallPolicyResponse: AWSDecodableShape {
        /// The number of capacity units currently consumed by the policy's stateful rules.
        public let consumedStatefulRuleCapacity: Int?
        /// The number of capacity units currently consumed by the policy's stateless rules.
        public let consumedStatelessRuleCapacity: Int?
        /// A description of the firewall policy.
        public let description: String?
        /// A complex type that contains the Amazon Web Services KMS encryption configuration settings for your firewall policy.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The Amazon Resource Name (ARN) of the firewall policy.  If this response is for a create request that had DryRun set to TRUE, then this ARN is a placeholder that isn't attached to a valid resource.
        public let firewallPolicyArn: String
        /// The unique identifier for the firewall policy.
        public let firewallPolicyId: String
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it.
        public let firewallPolicyName: String
        /// The current status of the firewall policy. You can retrieve this for a firewall policy by calling DescribeFirewallPolicy and providing the firewall policy's name or ARN.
        public let firewallPolicyStatus: ResourceStatus?
        /// The last time that the firewall policy was changed.
        public let lastModifiedTime: Date?
        /// The number of firewalls that are associated with this firewall policy.
        public let numberOfAssociations: Int?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?

        @inlinable
        public init(consumedStatefulRuleCapacity: Int? = nil, consumedStatelessRuleCapacity: Int? = nil, description: String? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, firewallPolicyArn: String, firewallPolicyId: String, firewallPolicyName: String, firewallPolicyStatus: ResourceStatus? = nil, lastModifiedTime: Date? = nil, numberOfAssociations: Int? = nil, tags: [Tag]? = nil) {
            self.consumedStatefulRuleCapacity = consumedStatefulRuleCapacity
            self.consumedStatelessRuleCapacity = consumedStatelessRuleCapacity
            self.description = description
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyId = firewallPolicyId
            self.firewallPolicyName = firewallPolicyName
            self.firewallPolicyStatus = firewallPolicyStatus
            self.lastModifiedTime = lastModifiedTime
            self.numberOfAssociations = numberOfAssociations
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case consumedStatefulRuleCapacity = "ConsumedStatefulRuleCapacity"
            case consumedStatelessRuleCapacity = "ConsumedStatelessRuleCapacity"
            case description = "Description"
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyId = "FirewallPolicyId"
            case firewallPolicyName = "FirewallPolicyName"
            case firewallPolicyStatus = "FirewallPolicyStatus"
            case lastModifiedTime = "LastModifiedTime"
            case numberOfAssociations = "NumberOfAssociations"
            case tags = "Tags"
        }
    }

    public struct FirewallStatus: AWSDecodableShape {
        /// Describes the capacity usage of the resources contained in a firewall's reference sets. Network Firewall calculates the capacity usage by taking an aggregated count of all of the resources used by all of the reference sets in a firewall.
        public let capacityUsageSummary: CapacityUsageSummary?
        /// The configuration sync state for the firewall. This summarizes the Config  settings in the SyncStates for this firewall status object.  When you create a firewall or update its configuration, for example by adding a rule group to its firewall policy, Network Firewall distributes the configuration changes to all Availability Zones that have subnets defined for the firewall. This summary indicates whether the configuration changes have been applied everywhere.  This status must be IN_SYNC for the firewall to be ready for use, but it doesn't indicate that the firewall is ready. The Status setting indicates firewall readiness. It's based on this setting and the readiness of the firewall endpoints to take traffic.
        public let configurationSyncStateSummary: ConfigurationSyncState
        /// The readiness of the configured firewall to handle network traffic across all of the Availability Zones where you have it configured. This setting is READY only when the ConfigurationSyncStateSummary value is IN_SYNC and the Attachment Status values for all of the configured subnets are READY.
        public let status: FirewallStatusValue
        /// Status for the subnets that you've configured in the firewall. This contains one array element per Availability Zone where you've configured a subnet in the firewall.  These objects provide detailed information for the settings  ConfigurationSyncStateSummary and Status.
        public let syncStates: [String: SyncState]?
        /// The synchronization state of the transit gateway attachment. This indicates whether the firewall's transit gateway configuration is properly synchronized and operational. Use this to verify that your transit gateway configuration changes have been applied.
        public let transitGatewayAttachmentSyncState: TransitGatewayAttachmentSyncState?

        @inlinable
        public init(capacityUsageSummary: CapacityUsageSummary? = nil, configurationSyncStateSummary: ConfigurationSyncState, status: FirewallStatusValue, syncStates: [String: SyncState]? = nil, transitGatewayAttachmentSyncState: TransitGatewayAttachmentSyncState? = nil) {
            self.capacityUsageSummary = capacityUsageSummary
            self.configurationSyncStateSummary = configurationSyncStateSummary
            self.status = status
            self.syncStates = syncStates
            self.transitGatewayAttachmentSyncState = transitGatewayAttachmentSyncState
        }

        private enum CodingKeys: String, CodingKey {
            case capacityUsageSummary = "CapacityUsageSummary"
            case configurationSyncStateSummary = "ConfigurationSyncStateSummary"
            case status = "Status"
            case syncStates = "SyncStates"
            case transitGatewayAttachmentSyncState = "TransitGatewayAttachmentSyncState"
        }
    }

    public struct Flow: AWSDecodableShape {
        /// Returned as info about age of the flows identified by the flow operation.
        public let age: Int?
        /// Returns the number of bytes received or transmitted in a specific flow.
        public let byteCount: Int64?
        public let destinationAddress: Address?
        /// The destination port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY.
        public let destinationPort: String?
        /// Returns the total number of data packets received or transmitted in a flow.
        public let packetCount: Int?
        /// The protocols to inspect for, specified using the assigned internet protocol number (IANA)  for each protocol. If not specified, this matches with any protocol.
        public let `protocol`: String?
        public let sourceAddress: Address?
        /// The source port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY.
        public let sourcePort: String?

        @inlinable
        public init(age: Int? = nil, byteCount: Int64? = nil, destinationAddress: Address? = nil, destinationPort: String? = nil, packetCount: Int? = nil, protocol: String? = nil, sourceAddress: Address? = nil, sourcePort: String? = nil) {
            self.age = age
            self.byteCount = byteCount
            self.destinationAddress = destinationAddress
            self.destinationPort = destinationPort
            self.packetCount = packetCount
            self.`protocol` = `protocol`
            self.sourceAddress = sourceAddress
            self.sourcePort = sourcePort
        }

        private enum CodingKeys: String, CodingKey {
            case age = "Age"
            case byteCount = "ByteCount"
            case destinationAddress = "DestinationAddress"
            case destinationPort = "DestinationPort"
            case packetCount = "PacketCount"
            case `protocol` = "Protocol"
            case sourceAddress = "SourceAddress"
            case sourcePort = "SourcePort"
        }
    }

    public struct FlowFilter: AWSEncodableShape & AWSDecodableShape {
        public let destinationAddress: Address?
        /// The destination port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY.
        public let destinationPort: String?
        /// The protocols to inspect for, specified using the assigned internet protocol number (IANA)  for each protocol. If not specified, this matches with any protocol.
        public let protocols: [String]?
        public let sourceAddress: Address?
        /// The source port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY.
        public let sourcePort: String?

        @inlinable
        public init(destinationAddress: Address? = nil, destinationPort: String? = nil, protocols: [String]? = nil, sourceAddress: Address? = nil, sourcePort: String? = nil) {
            self.destinationAddress = destinationAddress
            self.destinationPort = destinationPort
            self.protocols = protocols
            self.sourceAddress = sourceAddress
            self.sourcePort = sourcePort
        }

        public func validate(name: String) throws {
            try self.destinationAddress?.validate(name: "\(name).destinationAddress")
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, max: 1024)
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, min: 1)
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, pattern: "^.*$")
            try self.protocols?.forEach {
                try validate($0, name: "protocols[]", parent: name, max: 12)
                try validate($0, name: "protocols[]", parent: name, min: 1)
                try validate($0, name: "protocols[]", parent: name, pattern: "^.*$")
            }
            try self.sourceAddress?.validate(name: "\(name).sourceAddress")
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, max: 1024)
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, min: 1)
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, pattern: "^.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case destinationAddress = "DestinationAddress"
            case destinationPort = "DestinationPort"
            case protocols = "Protocols"
            case sourceAddress = "SourceAddress"
            case sourcePort = "SourcePort"
        }
    }

    public struct FlowOperation: AWSDecodableShape {
        /// Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let flowFilters: [FlowFilter]?
        /// The reqested FlowOperation ignores flows with an age (in seconds) lower than MinimumFlowAgeInSeconds.
        /// You provide this for start commands.
        public let minimumFlowAgeInSeconds: Int?

        @inlinable
        public init(flowFilters: [FlowFilter]? = nil, minimumFlowAgeInSeconds: Int? = nil) {
            self.flowFilters = flowFilters
            self.minimumFlowAgeInSeconds = minimumFlowAgeInSeconds
        }

        private enum CodingKeys: String, CodingKey {
            case flowFilters = "FlowFilters"
            case minimumFlowAgeInSeconds = "MinimumFlowAgeInSeconds"
        }
    }

    public struct FlowOperationMetadata: AWSDecodableShape {
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String?
        /// Returns the status of the flow operation. This string is returned in the responses to start, list, and describe commands. If the status is COMPLETED_WITH_ERRORS, results may be returned with any number of Flows missing from the response.
        /// If the status is FAILED, Flows returned will be empty.
        public let flowOperationStatus: FlowOperationStatus?
        /// Defines the type of FlowOperation.
        public let flowOperationType: FlowOperationType?
        /// A timestamp indicating when the Suricata engine identified flows impacted by an operation.
        public let flowRequestTimestamp: Date?

        @inlinable
        public init(flowOperationId: String? = nil, flowOperationStatus: FlowOperationStatus? = nil, flowOperationType: FlowOperationType? = nil, flowRequestTimestamp: Date? = nil) {
            self.flowOperationId = flowOperationId
            self.flowOperationStatus = flowOperationStatus
            self.flowOperationType = flowOperationType
            self.flowRequestTimestamp = flowRequestTimestamp
        }

        private enum CodingKeys: String, CodingKey {
            case flowOperationId = "FlowOperationId"
            case flowOperationStatus = "FlowOperationStatus"
            case flowOperationType = "FlowOperationType"
            case flowRequestTimestamp = "FlowRequestTimestamp"
        }
    }

    public struct FlowTimeouts: AWSEncodableShape & AWSDecodableShape {
        /// The number of seconds that can pass without any TCP traffic sent through the firewall before the firewall determines that the connection is idle. After the idle timeout passes, data packets are dropped, however, the next TCP SYN packet is considered a new flow and is processed by the firewall.  Clients or targets can use TCP keepalive packets to reset the idle timeout.  You can define the TcpIdleTimeoutSeconds value to be between 60 and 6000 seconds. If no value is provided, it defaults to 350 seconds.
        public let tcpIdleTimeoutSeconds: Int?

        @inlinable
        public init(tcpIdleTimeoutSeconds: Int? = nil) {
            self.tcpIdleTimeoutSeconds = tcpIdleTimeoutSeconds
        }

        private enum CodingKeys: String, CodingKey {
            case tcpIdleTimeoutSeconds = "TcpIdleTimeoutSeconds"
        }
    }

    public struct GetAnalysisReportResultsRequest: AWSEncodableShape {
        /// The unique ID of the query that ran when you requested an analysis report.
        public let analysisReportId: String
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(analysisReportId: String, firewallArn: String? = nil, firewallName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.analysisReportId = analysisReportId
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.analysisReportId, name: "analysisReportId", parent: name, max: 128)
            try self.validate(self.analysisReportId, name: "analysisReportId", parent: name, min: 1)
            try self.validate(self.analysisReportId, name: "analysisReportId", parent: name, pattern: "^\\S+$")
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case analysisReportId = "AnalysisReportId"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct GetAnalysisReportResultsResponse: AWSDecodableShape {
        /// Retrieves the results of a traffic analysis report.
        public let analysisReportResults: [AnalysisTypeReportResult]?
        /// The type of traffic that will be used to generate a report.
        public let analysisType: EnabledAnalysisType?
        /// The date and time, up to the current date, from which to stop retrieving analysis data,  in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ).
        public let endTime: Date?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The date and time the analysis report was ran.
        public let reportTime: Date?
        ///  The date and time within the last 30 days from which to start retrieving analysis data,  in UTC format (for example, YYYY-MM-DDTHH:MM:SSZ.
        public let startTime: Date?
        /// The status of the analysis report you specify. Statuses include RUNNING, COMPLETED, or FAILED.
        public let status: String?

        @inlinable
        public init(analysisReportResults: [AnalysisTypeReportResult]? = nil, analysisType: EnabledAnalysisType? = nil, endTime: Date? = nil, nextToken: String? = nil, reportTime: Date? = nil, startTime: Date? = nil, status: String? = nil) {
            self.analysisReportResults = analysisReportResults
            self.analysisType = analysisType
            self.endTime = endTime
            self.nextToken = nextToken
            self.reportTime = reportTime
            self.startTime = startTime
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case analysisReportResults = "AnalysisReportResults"
            case analysisType = "AnalysisType"
            case endTime = "EndTime"
            case nextToken = "NextToken"
            case reportTime = "ReportTime"
            case startTime = "StartTime"
            case status = "Status"
        }
    }

    public struct Header: AWSEncodableShape & AWSDecodableShape {
        /// The destination IP address or address range to inspect for, in CIDR notation. To match with any address, specify ANY.  Specify an IP address or a block of IP addresses in Classless Inter-Domain Routing (CIDR) notation. Network Firewall supports all address ranges for IPv4 and IPv6.  Examples:    To configure Network Firewall to inspect for the IP address 192.0.2.44, specify 192.0.2.44/32.   To configure Network Firewall to inspect for IP addresses from 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24.   To configure Network Firewall to inspect for the IP address 1111:0000:0000:0000:0000:0000:0000:0111, specify 1111:0000:0000:0000:0000:0000:0000:0111/128.   To configure Network Firewall to inspect for IP addresses from 1111:0000:0000:0000:0000:0000:0000:0000 to 1111:0000:0000:0000:ffff:ffff:ffff:ffff, specify 1111:0000:0000:0000:0000:0000:0000:0000/64.   For more information about CIDR notation, see the Wikipedia entry Classless Inter-Domain Routing.
        public let destination: String
        /// The destination port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY.
        public let destinationPort: String
        /// The direction of traffic flow to inspect. If set to ANY, the inspection matches bidirectional traffic, both from the source to the destination and from the destination to the source. If set to FORWARD, the inspection only matches traffic going from the source to the destination.
        public let direction: StatefulRuleDirection
        /// The protocol to inspect for. To specify all, you can use IP, because all traffic on Amazon Web Services and on the internet is IP.
        public let `protocol`: StatefulRuleProtocol
        /// The source IP address or address range to inspect for, in CIDR notation. To match with any address, specify ANY.  Specify an IP address or a block of IP addresses in Classless Inter-Domain Routing (CIDR) notation. Network Firewall supports all address ranges for IPv4 and IPv6.  Examples:    To configure Network Firewall to inspect for the IP address 192.0.2.44, specify 192.0.2.44/32.   To configure Network Firewall to inspect for IP addresses from 192.0.2.0 to 192.0.2.255, specify 192.0.2.0/24.   To configure Network Firewall to inspect for the IP address 1111:0000:0000:0000:0000:0000:0000:0111, specify 1111:0000:0000:0000:0000:0000:0000:0111/128.   To configure Network Firewall to inspect for IP addresses from 1111:0000:0000:0000:0000:0000:0000:0000 to 1111:0000:0000:0000:ffff:ffff:ffff:ffff, specify 1111:0000:0000:0000:0000:0000:0000:0000/64.   For more information about CIDR notation, see the Wikipedia entry Classless Inter-Domain Routing.
        public let source: String
        /// The source port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY.
        public let sourcePort: String

        @inlinable
        public init(destination: String, destinationPort: String, direction: StatefulRuleDirection, protocol: StatefulRuleProtocol, source: String, sourcePort: String) {
            self.destination = destination
            self.destinationPort = destinationPort
            self.direction = direction
            self.`protocol` = `protocol`
            self.source = source
            self.sourcePort = sourcePort
        }

        public func validate(name: String) throws {
            try self.validate(self.destination, name: "destination", parent: name, max: 1024)
            try self.validate(self.destination, name: "destination", parent: name, min: 1)
            try self.validate(self.destination, name: "destination", parent: name, pattern: "^.*$")
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, max: 1024)
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, min: 1)
            try self.validate(self.destinationPort, name: "destinationPort", parent: name, pattern: "^.*$")
            try self.validate(self.source, name: "source", parent: name, max: 1024)
            try self.validate(self.source, name: "source", parent: name, min: 1)
            try self.validate(self.source, name: "source", parent: name, pattern: "^.*$")
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, max: 1024)
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, min: 1)
            try self.validate(self.sourcePort, name: "sourcePort", parent: name, pattern: "^.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case destination = "Destination"
            case destinationPort = "DestinationPort"
            case direction = "Direction"
            case `protocol` = "Protocol"
            case source = "Source"
            case sourcePort = "SourcePort"
        }
    }

    public struct Hits: AWSDecodableShape {
        /// The number of attempts made to access a domain.
        public let count: Int?

        @inlinable
        public init(count: Int? = nil) {
            self.count = count
        }

        private enum CodingKeys: String, CodingKey {
            case count = "Count"
        }
    }

    public struct IPSet: AWSEncodableShape & AWSDecodableShape {
        /// The list of IP addresses and address ranges, in CIDR notation.
        public let definition: [String]

        @inlinable
        public init(definition: [String]) {
            self.definition = definition
        }

        public func validate(name: String) throws {
            try self.definition.forEach {
                try validate($0, name: "definition[]", parent: name, min: 1)
                try validate($0, name: "definition[]", parent: name, pattern: "^.*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case definition = "Definition"
        }
    }

    public struct IPSetMetadata: AWSDecodableShape {
        /// Describes the total number of CIDR blocks currently in use by the IP set references in a firewall. To determine how many CIDR blocks are available for you to use in a firewall, you can call AvailableCIDRCount.
        public let resolvedCIDRCount: Int?

        @inlinable
        public init(resolvedCIDRCount: Int? = nil) {
            self.resolvedCIDRCount = resolvedCIDRCount
        }

        private enum CodingKeys: String, CodingKey {
            case resolvedCIDRCount = "ResolvedCIDRCount"
        }
    }

    public struct IPSetReference: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the resource that you are referencing in your rule group.
        public let referenceArn: String?

        @inlinable
        public init(referenceArn: String? = nil) {
            self.referenceArn = referenceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.referenceArn, name: "referenceArn", parent: name, max: 256)
            try self.validate(self.referenceArn, name: "referenceArn", parent: name, min: 1)
            try self.validate(self.referenceArn, name: "referenceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case referenceArn = "ReferenceArn"
        }
    }

    public struct ListAnalysisReportsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListAnalysisReportsResponse: AWSDecodableShape {
        /// The id and ReportTime associated with a requested analysis report. Does not provide the status of the analysis report.
        public let analysisReports: [AnalysisReport]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(analysisReports: [AnalysisReport]? = nil, nextToken: String? = nil) {
            self.analysisReports = analysisReports
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case analysisReports = "AnalysisReports"
            case nextToken = "NextToken"
        }
    }

    public struct ListFirewallPoliciesRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListFirewallPoliciesResponse: AWSDecodableShape {
        /// The metadata for the firewall policies. Depending on your setting for max results and the number of firewall policies that you have, this might not be the full list.
        public let firewallPolicies: [FirewallPolicyMetadata]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(firewallPolicies: [FirewallPolicyMetadata]? = nil, nextToken: String? = nil) {
            self.firewallPolicies = firewallPolicies
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicies = "FirewallPolicies"
            case nextToken = "NextToken"
        }
    }

    public struct ListFirewallsRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The unique identifiers of the VPCs that you want Network Firewall to retrieve the firewalls for. Leave this blank to retrieve all firewalls that you have defined.
        public let vpcIds: [String]?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, vpcIds: [String]? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.vpcIds = vpcIds
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
            try self.vpcIds?.forEach {
                try validate($0, name: "vpcIds[]", parent: name, max: 128)
                try validate($0, name: "vpcIds[]", parent: name, min: 1)
                try validate($0, name: "vpcIds[]", parent: name, pattern: "^vpc-[0-9a-f]+$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case vpcIds = "VpcIds"
        }
    }

    public struct ListFirewallsResponse: AWSDecodableShape {
        /// The firewall metadata objects for the VPCs that you specified. Depending on your setting for max results and the number of firewalls you have, a single call might not be the full list.
        public let firewalls: [FirewallMetadata]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(firewalls: [FirewallMetadata]? = nil, nextToken: String? = nil) {
            self.firewalls = firewalls
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewalls = "Firewalls"
            case nextToken = "NextToken"
        }
    }

    public struct ListFlowOperationResultsRequest: AWSEncodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?
        /// A unique identifier for the primary endpoint associated with a firewall.
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String, flowOperationId: String, maxResults: Int? = nil, nextToken: String? = nil, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowOperationId = flowOperationId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.flowOperationId, name: "flowOperationId", parent: name, max: 36)
            try self.validate(self.flowOperationId, name: "flowOperationId", parent: name, min: 36)
            try self.validate(self.flowOperationId, name: "flowOperationId", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, max: 256)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, min: 5)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, pattern: "^vpce-[a-zA-Z0-9]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowOperationId = "FlowOperationId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct ListFlowOperationResultsResponse: AWSDecodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String?
        /// Returns the status of the flow operation. This string is returned in the responses to start, list, and describe commands. If the status is COMPLETED_WITH_ERRORS, results may be returned with any number of Flows missing from the response.
        /// If the status is FAILED, Flows returned will be empty.
        public let flowOperationStatus: FlowOperationStatus?
        /// A timestamp indicating when the Suricata engine identified flows impacted by an operation.
        public let flowRequestTimestamp: Date?
        /// Any number of arrays, where each array is a single flow identified in the scope of the operation.
        /// If multiple flows were in the scope of the operation, multiple Flows arrays are returned.
        public let flows: [Flow]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// If the asynchronous operation fails, Network Firewall populates this with the reason for the error or failure.  Options include Flow operation error and Flow timeout.
        public let statusMessage: String?
        public let vpcEndpointAssociationArn: String?
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String? = nil, flowOperationId: String? = nil, flowOperationStatus: FlowOperationStatus? = nil, flowRequestTimestamp: Date? = nil, flows: [Flow]? = nil, nextToken: String? = nil, statusMessage: String? = nil, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowOperationId = flowOperationId
            self.flowOperationStatus = flowOperationStatus
            self.flowRequestTimestamp = flowRequestTimestamp
            self.flows = flows
            self.nextToken = nextToken
            self.statusMessage = statusMessage
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowOperationId = "FlowOperationId"
            case flowOperationStatus = "FlowOperationStatus"
            case flowRequestTimestamp = "FlowRequestTimestamp"
            case flows = "Flows"
            case nextToken = "NextToken"
            case statusMessage = "StatusMessage"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct ListFlowOperationsRequest: AWSEncodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        /// An optional string that defines whether any or all operation types are returned.
        public let flowOperationType: FlowOperationType?
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?
        /// A unique identifier for the primary endpoint associated with a firewall.
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String, flowOperationType: FlowOperationType? = nil, maxResults: Int? = nil, nextToken: String? = nil, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowOperationType = flowOperationType
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, max: 256)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, min: 5)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, pattern: "^vpce-[a-zA-Z0-9]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowOperationType = "FlowOperationType"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct ListFlowOperationsResponse: AWSDecodableShape {
        /// Flow operations let you manage the flows tracked in the flow table, also known as the firewall table. A flow is network traffic that is monitored by a firewall, either by stateful or stateless rules.
        /// For traffic to be considered part of a flow, it must share Destination, DestinationPort, Direction, Protocol, Source, and SourcePort.
        public let flowOperations: [FlowOperationMetadata]?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(flowOperations: [FlowOperationMetadata]? = nil, nextToken: String? = nil) {
            self.flowOperations = flowOperations
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case flowOperations = "FlowOperations"
            case nextToken = "NextToken"
        }
    }

    public struct ListRuleGroupsRequest: AWSEncodableShape {
        /// Indicates the general category of the Amazon Web Services managed rule group.
        public let managedType: ResourceManagedType?
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The scope of the request. The default setting of ACCOUNT or a setting of NULL returns all of the rule groups in your account. A setting of MANAGED returns all available managed rule groups.
        public let scope: ResourceManagedStatus?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains stateless rules. If it is stateful, it contains stateful rules.
        public let type: RuleGroupType?

        @inlinable
        public init(managedType: ResourceManagedType? = nil, maxResults: Int? = nil, nextToken: String? = nil, scope: ResourceManagedStatus? = nil, type: RuleGroupType? = nil) {
            self.managedType = managedType
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.scope = scope
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case managedType = "ManagedType"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case scope = "Scope"
            case type = "Type"
        }
    }

    public struct ListRuleGroupsResponse: AWSDecodableShape {
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The rule group metadata objects that you've defined. Depending on your setting for max results and the number of rule groups, this might not be the full list.
        public let ruleGroups: [RuleGroupMetadata]?

        @inlinable
        public init(nextToken: String? = nil, ruleGroups: [RuleGroupMetadata]? = nil) {
            self.nextToken = nextToken
            self.ruleGroups = ruleGroups
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case ruleGroups = "RuleGroups"
        }
    }

    public struct ListTLSInspectionConfigurationsRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListTLSInspectionConfigurationsResponse: AWSDecodableShape {
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The TLS inspection configuration metadata objects that you've defined. Depending on your setting for max results and the number of TLS inspection configurations, this might not be the full list.
        public let tlsInspectionConfigurations: [TLSInspectionConfigurationMetadata]?

        @inlinable
        public init(nextToken: String? = nil, tlsInspectionConfigurations: [TLSInspectionConfigurationMetadata]? = nil) {
            self.nextToken = nextToken
            self.tlsInspectionConfigurations = tlsInspectionConfigurations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tlsInspectionConfigurations = "TLSInspectionConfigurations"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, resourceArn: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 0)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
            case resourceArn = "ResourceArn"
        }
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The tags that are associated with the resource.
        public let tags: [Tag]?

        @inlinable
        public init(nextToken: String? = nil, tags: [Tag]? = nil) {
            self.nextToken = nextToken
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case tags = "Tags"
        }
    }

    public struct ListVpcEndpointAssociationsRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. If you don't specify this, Network Firewall retrieves all VPC endpoint associations that you have defined.
        public let firewallArn: String?
        /// The maximum number of objects that you want Network Firewall to return for this request. If more objects are available, in the response, Network Firewall provides a NextToken value that you can use in a subsequent call to get the next batch of objects.
        public let maxResults: Int?
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?

        @inlinable
        public init(firewallArn: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.firewallArn = firewallArn
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 100)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 4096)
            try self.validate(self.nextToken, name: "nextToken", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^[0-9A-Za-z:\\/+=]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListVpcEndpointAssociationsResponse: AWSDecodableShape {
        /// When you request a list of objects with a MaxResults setting, if the number of objects that are still available for retrieval exceeds the maximum you requested, Network Firewall returns a NextToken value in the response. To retrieve the next batch of objects, use the token returned from the prior request in your next request.
        public let nextToken: String?
        /// The VPC endpoint assocation metadata objects for the firewall that you specified. If you didn't specify a firewall, this is all VPC endpoint associations that you have defined.  Depending on your setting for max results and the number of firewalls you have, a single call might not be the full list.
        public let vpcEndpointAssociations: [VpcEndpointAssociationMetadata]?

        @inlinable
        public init(nextToken: String? = nil, vpcEndpointAssociations: [VpcEndpointAssociationMetadata]? = nil) {
            self.nextToken = nextToken
            self.vpcEndpointAssociations = vpcEndpointAssociations
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "NextToken"
            case vpcEndpointAssociations = "VpcEndpointAssociations"
        }
    }

    public struct LogDestinationConfig: AWSEncodableShape & AWSDecodableShape {
        /// The named location for the logs, provided in a key:value mapping that is specific to the chosen destination type.    For an Amazon S3 bucket, provide the name of the bucket, with key bucketName, and optionally provide a prefix, with key prefix.  The following example specifies an Amazon S3 bucket named DOC-EXAMPLE-BUCKET and the prefix alerts:   "LogDestination": { "bucketName": "DOC-EXAMPLE-BUCKET", "prefix": "alerts" }    For a CloudWatch log group, provide the name of the CloudWatch log group, with key logGroup. The following example specifies a log group named alert-log-group:   "LogDestination": { "logGroup": "alert-log-group" }    For a Firehose delivery stream, provide the name of the delivery stream, with key deliveryStream. The following example specifies a delivery stream named alert-delivery-stream:   "LogDestination": { "deliveryStream": "alert-delivery-stream" }
        public let logDestination: [String: String]
        /// The type of storage destination to send these logs to. You can send logs to an Amazon S3 bucket, a CloudWatch log group, or a Firehose delivery stream.
        public let logDestinationType: LogDestinationType
        /// The type of log to record. You can record the following types of logs from your Network Firewall stateful engine.    ALERT - Logs for traffic that matches your stateful rules and that have an action that sends an alert. A stateful rule sends alerts for the rule actions DROP, ALERT, and REJECT. For more information, see StatefulRule.    FLOW - Standard network traffic flow logs. The stateful rules engine records flow logs for all network traffic that it receives. Each flow log record captures the network flow for a specific standard stateless rule group.    TLS - Logs for events that are related to TLS inspection. For more information, see   Inspecting SSL/TLS traffic with TLS inspection configurations  in the Network Firewall Developer Guide.
        public let logType: LogType

        @inlinable
        public init(logDestination: [String: String], logDestinationType: LogDestinationType, logType: LogType) {
            self.logDestination = logDestination
            self.logDestinationType = logDestinationType
            self.logType = logType
        }

        public func validate(name: String) throws {
            try self.logDestination.forEach {
                try validate($0.key, name: "logDestination.key", parent: name, max: 50)
                try validate($0.key, name: "logDestination.key", parent: name, min: 3)
                try validate($0.key, name: "logDestination.key", parent: name, pattern: "^[0-9A-Za-z.\\-_@\\/]+$")
                try validate($0.value, name: "logDestination[\"\($0.key)\"]", parent: name, max: 1024)
                try validate($0.value, name: "logDestination[\"\($0.key)\"]", parent: name, min: 1)
                try validate($0.value, name: "logDestination[\"\($0.key)\"]", parent: name, pattern: "^[\\s\\S]*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case logDestination = "LogDestination"
            case logDestinationType = "LogDestinationType"
            case logType = "LogType"
        }
    }

    public struct LoggingConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Defines the logging destinations for the logs for a firewall. Network Firewall generates logs for stateful rule groups.
        public let logDestinationConfigs: [LogDestinationConfig]

        @inlinable
        public init(logDestinationConfigs: [LogDestinationConfig]) {
            self.logDestinationConfigs = logDestinationConfigs
        }

        public func validate(name: String) throws {
            try self.logDestinationConfigs.forEach {
                try $0.validate(name: "\(name).logDestinationConfigs[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case logDestinationConfigs = "LogDestinationConfigs"
        }
    }

    public struct MatchAttributes: AWSEncodableShape & AWSDecodableShape {
        /// The destination port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY. This setting is only used for protocols 6 (TCP) and 17 (UDP).
        public let destinationPorts: [PortRange]?
        /// The destination IP addresses and address ranges to inspect for, in CIDR notation. If not specified, this matches with any destination address.
        public let destinations: [Address]?
        /// The protocols to inspect for, specified using the assigned internet protocol number (IANA)  for each protocol. If not specified, this matches with any protocol.
        public let protocols: [Int]?
        /// The source port to inspect for. You can specify an individual port,  for example 1994 and you can specify a port range, for example 1990:1994.  To match with any port, specify ANY. If not specified, this matches with any source port. This setting is only used for protocols 6 (TCP) and 17 (UDP).
        public let sourcePorts: [PortRange]?
        /// The source IP addresses and address ranges to inspect for, in CIDR notation. If not specified, this matches with any source address.
        public let sources: [Address]?
        /// The TCP flags and masks to inspect for. If not specified, this matches with any settings. This setting is only used for protocol 6 (TCP).
        public let tcpFlags: [TCPFlagField]?

        @inlinable
        public init(destinationPorts: [PortRange]? = nil, destinations: [Address]? = nil, protocols: [Int]? = nil, sourcePorts: [PortRange]? = nil, sources: [Address]? = nil, tcpFlags: [TCPFlagField]? = nil) {
            self.destinationPorts = destinationPorts
            self.destinations = destinations
            self.protocols = protocols
            self.sourcePorts = sourcePorts
            self.sources = sources
            self.tcpFlags = tcpFlags
        }

        public func validate(name: String) throws {
            try self.destinationPorts?.forEach {
                try $0.validate(name: "\(name).destinationPorts[]")
            }
            try self.destinations?.forEach {
                try $0.validate(name: "\(name).destinations[]")
            }
            try self.protocols?.forEach {
                try validate($0, name: "protocols[]", parent: name, max: 255)
                try validate($0, name: "protocols[]", parent: name, min: 0)
            }
            try self.sourcePorts?.forEach {
                try $0.validate(name: "\(name).sourcePorts[]")
            }
            try self.sources?.forEach {
                try $0.validate(name: "\(name).sources[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case destinationPorts = "DestinationPorts"
            case destinations = "Destinations"
            case protocols = "Protocols"
            case sourcePorts = "SourcePorts"
            case sources = "Sources"
            case tcpFlags = "TCPFlags"
        }
    }

    public struct PerObjectStatus: AWSDecodableShape {
        /// Indicates whether this object is in sync with the version indicated in the update token.
        public let syncStatus: PerObjectSyncStatus?
        /// The current version of the object that is either in sync or pending synchronization.
        public let updateToken: String?

        @inlinable
        public init(syncStatus: PerObjectSyncStatus? = nil, updateToken: String? = nil) {
            self.syncStatus = syncStatus
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case syncStatus = "SyncStatus"
            case updateToken = "UpdateToken"
        }
    }

    public struct PolicyVariables: AWSEncodableShape & AWSDecodableShape {
        /// The IPv4 or IPv6 addresses in CIDR notation to use for the Suricata HOME_NET variable. If your firewall uses an inspection VPC, you might want to override the HOME_NET variable with the CIDRs of your home networks. If you don't override HOME_NET with your own CIDRs, Network Firewall by default uses the CIDR of your inspection VPC.
        public let ruleVariables: [String: IPSet]?

        @inlinable
        public init(ruleVariables: [String: IPSet]? = nil) {
            self.ruleVariables = ruleVariables
        }

        public func validate(name: String) throws {
            try self.ruleVariables?.forEach {
                try validate($0.key, name: "ruleVariables.key", parent: name, max: 32)
                try validate($0.key, name: "ruleVariables.key", parent: name, min: 1)
                try validate($0.key, name: "ruleVariables.key", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_]*$")
                try $0.value.validate(name: "\(name).ruleVariables[\"\($0.key)\"]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case ruleVariables = "RuleVariables"
        }
    }

    public struct PortRange: AWSEncodableShape & AWSDecodableShape {
        /// The lower limit of the port range. This must be less than or equal to the ToPort specification.
        public let fromPort: Int
        /// The upper limit of the port range. This must be greater than or equal to the FromPort specification.
        public let toPort: Int

        @inlinable
        public init(fromPort: Int, toPort: Int) {
            self.fromPort = fromPort
            self.toPort = toPort
        }

        public func validate(name: String) throws {
            try self.validate(self.fromPort, name: "fromPort", parent: name, max: 65535)
            try self.validate(self.fromPort, name: "fromPort", parent: name, min: 0)
            try self.validate(self.toPort, name: "toPort", parent: name, max: 65535)
            try self.validate(self.toPort, name: "toPort", parent: name, min: 0)
        }

        private enum CodingKeys: String, CodingKey {
            case fromPort = "FromPort"
            case toPort = "ToPort"
        }
    }

    public struct PortSet: AWSEncodableShape & AWSDecodableShape {
        /// The set of port ranges.
        public let definition: [String]?

        @inlinable
        public init(definition: [String]? = nil) {
            self.definition = definition
        }

        public func validate(name: String) throws {
            try self.definition?.forEach {
                try validate($0, name: "definition[]", parent: name, min: 1)
                try validate($0, name: "definition[]", parent: name, pattern: "^.*$")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case definition = "Definition"
        }
    }

    public struct PublishMetricAction: AWSEncodableShape & AWSDecodableShape {
        public let dimensions: [Dimension]

        @inlinable
        public init(dimensions: [Dimension]) {
            self.dimensions = dimensions
        }

        public func validate(name: String) throws {
            try self.dimensions.forEach {
                try $0.validate(name: "\(name).dimensions[]")
            }
            try self.validate(self.dimensions, name: "dimensions", parent: name, max: 1)
            try self.validate(self.dimensions, name: "dimensions", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case dimensions = "Dimensions"
        }
    }

    public struct PutResourcePolicyRequest: AWSEncodableShape {
        /// The IAM policy statement that lists the accounts that you want to share your Network Firewall resources with and the operations that you want the accounts to be able to perform.  For a rule group resource, you can specify the following operations in the Actions section of the statement:   network-firewall:CreateFirewallPolicy   network-firewall:UpdateFirewallPolicy   network-firewall:ListRuleGroups   For a firewall policy resource, you can specify the following operations in the Actions section of the statement:   network-firewall:AssociateFirewallPolicy   network-firewall:ListFirewallPolicies   For a firewall resource, you can specify the following operations in the Actions section of the statement:   network-firewall:CreateVpcEndpointAssociation   network-firewall:DescribeFirewallMetadata   network-firewall:ListFirewalls   In the Resource section of the statement, you specify the ARNs for the Network Firewall resources that you want to share with the account that you specified in Arn.
        public let policy: String
        /// The Amazon Resource Name (ARN) of the account that you want to share your Network Firewall resources with.
        public let resourceArn: String

        @inlinable
        public init(policy: String, resourceArn: String) {
            self.policy = policy
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.policy, name: "policy", parent: name, max: 395000)
            try self.validate(self.policy, name: "policy", parent: name, min: 1)
            try self.validate(self.policy, name: "policy", parent: name, pattern: "\\S")
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
            case resourceArn = "ResourceArn"
        }
    }

    public struct PutResourcePolicyResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ReferenceSets: AWSEncodableShape & AWSDecodableShape {
        /// The list of IP set references.
        public let ipSetReferences: [String: IPSetReference]?

        @inlinable
        public init(ipSetReferences: [String: IPSetReference]? = nil) {
            self.ipSetReferences = ipSetReferences
        }

        public func validate(name: String) throws {
            try self.ipSetReferences?.forEach {
                try validate($0.key, name: "ipSetReferences.key", parent: name, max: 32)
                try validate($0.key, name: "ipSetReferences.key", parent: name, min: 1)
                try validate($0.key, name: "ipSetReferences.key", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_]*$")
                try $0.value.validate(name: "\(name).ipSetReferences[\"\($0.key)\"]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case ipSetReferences = "IPSetReferences"
        }
    }

    public struct RejectNetworkFirewallTransitGatewayAttachmentRequest: AWSEncodableShape {
        /// Required. The unique identifier of the transit gateway attachment to reject. This ID is returned in the response when creating a transit gateway-attached firewall.
        public let transitGatewayAttachmentId: String

        @inlinable
        public init(transitGatewayAttachmentId: String) {
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
        }

        public func validate(name: String) throws {
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, max: 128)
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, min: 1)
            try self.validate(self.transitGatewayAttachmentId, name: "transitGatewayAttachmentId", parent: name, pattern: "^tgw-attach-[0-9a-z]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
        }
    }

    public struct RejectNetworkFirewallTransitGatewayAttachmentResponse: AWSDecodableShape {
        /// The unique identifier of the transit gateway attachment that was rejected.
        public let transitGatewayAttachmentId: String
        /// The current status of the transit gateway attachment. Valid values are:    CREATING - The attachment is being created    DELETING - The attachment is being deleted    DELETED - The attachment has been deleted    FAILED - The attachment creation has failed and cannot be recovered    ERROR - The attachment is in an error state that might be recoverable    READY - The attachment is active and processing traffic    PENDING_ACCEPTANCE - The attachment is waiting to be accepted    REJECTING - The attachment is in the process of being rejected    REJECTED - The attachment has been rejected   For information about troubleshooting endpoint failures, see Troubleshooting firewall endpoint failures in the Network Firewall Developer Guide.
        public let transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus

        @inlinable
        public init(transitGatewayAttachmentId: String, transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus) {
            self.transitGatewayAttachmentId = transitGatewayAttachmentId
            self.transitGatewayAttachmentStatus = transitGatewayAttachmentStatus
        }

        private enum CodingKeys: String, CodingKey {
            case transitGatewayAttachmentId = "TransitGatewayAttachmentId"
            case transitGatewayAttachmentStatus = "TransitGatewayAttachmentStatus"
        }
    }

    public struct RuleDefinition: AWSEncodableShape & AWSDecodableShape {
        /// The actions to take on a packet that matches one of the stateless rule definition's match attributes. You must specify a standard action and you can add custom actions.   Network Firewall only forwards a packet for stateful rule inspection if you specify aws:forward_to_sfe for a rule that the packet matches, or if the packet doesn't match any stateless rule and you specify aws:forward_to_sfe for the StatelessDefaultActions setting for the FirewallPolicy.  For every rule, you must specify exactly one of the following standard actions.     aws:pass - Discontinues all inspection of the packet and permits it to go to its intended destination.    aws:drop - Discontinues all inspection of the packet and blocks it from going to its intended destination.    aws:forward_to_sfe - Discontinues stateless inspection of the packet and forwards it to the stateful rule engine for inspection.    Additionally, you can specify a custom action. To do this, you define a custom action by name and type, then provide the name you've assigned to the action in this Actions setting. For information about the options, see CustomAction.  To provide more than one action in this setting, separate the settings with a comma. For example, if you have a custom PublishMetrics action that you've named MyMetricsAction, then you could specify the standard action aws:pass and the custom action with [“aws:pass”, “MyMetricsAction”].
        public let actions: [String]
        /// Criteria for Network Firewall to use to inspect an individual packet in stateless rule inspection. Each match attributes set can include one or more items such as IP address, CIDR range, port number, protocol, and TCP flags.
        public let matchAttributes: MatchAttributes

        @inlinable
        public init(actions: [String], matchAttributes: MatchAttributes) {
            self.actions = actions
            self.matchAttributes = matchAttributes
        }

        public func validate(name: String) throws {
            try self.matchAttributes.validate(name: "\(name).matchAttributes")
        }

        private enum CodingKeys: String, CodingKey {
            case actions = "Actions"
            case matchAttributes = "MatchAttributes"
        }
    }

    public struct RuleGroup: AWSEncodableShape & AWSDecodableShape {
        /// The list of a rule group's reference sets.
        public let referenceSets: ReferenceSets?
        /// The stateful rules or stateless rules for the rule group.
        public let rulesSource: RulesSource
        /// Settings that are available for use in the rules in the rule group. You can only use these for stateful rule groups.
        public let ruleVariables: RuleVariables?
        /// Additional options governing how Network Firewall handles stateful rules. The policies where you use your stateful rule group must have stateful rule options settings that are compatible with these settings. Some limitations apply; for more information, see Strict evaluation order in the Network Firewall Developer Guide.
        public let statefulRuleOptions: StatefulRuleOptions?

        @inlinable
        public init(referenceSets: ReferenceSets? = nil, rulesSource: RulesSource, ruleVariables: RuleVariables? = nil, statefulRuleOptions: StatefulRuleOptions? = nil) {
            self.referenceSets = referenceSets
            self.rulesSource = rulesSource
            self.ruleVariables = ruleVariables
            self.statefulRuleOptions = statefulRuleOptions
        }

        public func validate(name: String) throws {
            try self.referenceSets?.validate(name: "\(name).referenceSets")
            try self.rulesSource.validate(name: "\(name).rulesSource")
            try self.ruleVariables?.validate(name: "\(name).ruleVariables")
        }

        private enum CodingKeys: String, CodingKey {
            case referenceSets = "ReferenceSets"
            case rulesSource = "RulesSource"
            case ruleVariables = "RuleVariables"
            case statefulRuleOptions = "StatefulRuleOptions"
        }
    }

    public struct RuleGroupMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the rule group.
        public let arn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let name: String?

        @inlinable
        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct RuleGroupResponse: AWSDecodableShape {
        /// The list of analysis results for AnalyzeRuleGroup. If you set AnalyzeRuleGroup to TRUE in CreateRuleGroup, UpdateRuleGroup, or DescribeRuleGroup, Network Firewall analyzes the rule group and identifies the rules that might adversely effect your firewall's functionality. For example, if Network Firewall detects a rule that's routing traffic asymmetrically, which impacts the service's ability to properly process traffic, the service includes the rule in the list of analysis results.
        public let analysisResults: [AnalysisResult]?
        /// The maximum operating resources that this rule group can use. Rule group capacity is fixed at creation. When you update a rule group, you are limited to this capacity. When you reference a rule group from a firewall policy, Network Firewall reserves this capacity for the rule group.  You can retrieve the capacity that would be required for a rule group before you create the rule group by calling CreateRuleGroup with DryRun set to TRUE.
        public let capacity: Int?
        /// The number of capacity units currently consumed by the rule group rules.
        public let consumedCapacity: Int?
        /// A description of the rule group.
        public let description: String?
        /// A complex type that contains the Amazon Web Services KMS encryption configuration settings for your rule group.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The last time that the rule group was changed.
        public let lastModifiedTime: Date?
        /// The number of firewall policies that use this rule group.
        public let numberOfAssociations: Int?
        /// The Amazon Resource Name (ARN) of the rule group.  If this response is for a create request that had DryRun set to TRUE, then this ARN is a placeholder that isn't attached to a valid resource.
        public let ruleGroupArn: String
        /// The unique identifier for the rule group.
        public let ruleGroupId: String
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it.
        public let ruleGroupName: String
        /// Detailed information about the current status of a rule group.
        public let ruleGroupStatus: ResourceStatus?
        /// The Amazon Resource Name (ARN) of the Amazon Simple Notification Service SNS topic that's
        /// used to record changes to the managed rule group. You can subscribe to the SNS topic to receive
        /// notifications when the managed rule group is modified, such as for new versions and for version
        /// expiration. For more information, see the Amazon Simple Notification Service Developer Guide..
        public let snsTopic: String?
        /// A complex type that contains metadata about the rule group that your own rule group is copied from. You can use the metadata to track the version updates made to the originating rule group.
        public let sourceMetadata: SourceMetadata?
        /// A complex type containing the currently selected rule option fields that will be displayed for rule summarization returned by DescribeRuleGroupSummary.   The RuleOptions specified in SummaryConfiguration    Rule metadata organization preferences
        public let summaryConfiguration: SummaryConfiguration?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.
        public let type: RuleGroupType?

        @inlinable
        public init(analysisResults: [AnalysisResult]? = nil, capacity: Int? = nil, consumedCapacity: Int? = nil, description: String? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, lastModifiedTime: Date? = nil, numberOfAssociations: Int? = nil, ruleGroupArn: String, ruleGroupId: String, ruleGroupName: String, ruleGroupStatus: ResourceStatus? = nil, snsTopic: String? = nil, sourceMetadata: SourceMetadata? = nil, summaryConfiguration: SummaryConfiguration? = nil, tags: [Tag]? = nil, type: RuleGroupType? = nil) {
            self.analysisResults = analysisResults
            self.capacity = capacity
            self.consumedCapacity = consumedCapacity
            self.description = description
            self.encryptionConfiguration = encryptionConfiguration
            self.lastModifiedTime = lastModifiedTime
            self.numberOfAssociations = numberOfAssociations
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupId = ruleGroupId
            self.ruleGroupName = ruleGroupName
            self.ruleGroupStatus = ruleGroupStatus
            self.snsTopic = snsTopic
            self.sourceMetadata = sourceMetadata
            self.summaryConfiguration = summaryConfiguration
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case analysisResults = "AnalysisResults"
            case capacity = "Capacity"
            case consumedCapacity = "ConsumedCapacity"
            case description = "Description"
            case encryptionConfiguration = "EncryptionConfiguration"
            case lastModifiedTime = "LastModifiedTime"
            case numberOfAssociations = "NumberOfAssociations"
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupId = "RuleGroupId"
            case ruleGroupName = "RuleGroupName"
            case ruleGroupStatus = "RuleGroupStatus"
            case snsTopic = "SnsTopic"
            case sourceMetadata = "SourceMetadata"
            case summaryConfiguration = "SummaryConfiguration"
            case tags = "Tags"
            case type = "Type"
        }
    }

    public struct RuleOption: AWSEncodableShape & AWSDecodableShape {
        /// The keyword for the Suricata compatible rule option. You must include a sid (signature ID), and can optionally include other keywords. For information about Suricata compatible keywords, see Rule options in the Suricata documentation.
        public let keyword: String
        /// The settings of the Suricata compatible rule option. Rule options have zero or more setting values, and the number of possible and required settings depends on the Keyword. For more information about the settings for specific options, see Rule options.
        public let settings: [String]?

        @inlinable
        public init(keyword: String, settings: [String]? = nil) {
            self.keyword = keyword
            self.settings = settings
        }

        public func validate(name: String) throws {
            try self.validate(self.keyword, name: "keyword", parent: name, max: 128)
            try self.validate(self.keyword, name: "keyword", parent: name, min: 1)
            try self.validate(self.keyword, name: "keyword", parent: name, pattern: ".*")
            try self.settings?.forEach {
                try validate($0, name: "settings[]", parent: name, max: 8192)
                try validate($0, name: "settings[]", parent: name, min: 1)
                try validate($0, name: "settings[]", parent: name, pattern: ".*")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case keyword = "Keyword"
            case settings = "Settings"
        }
    }

    public struct RuleSummary: AWSDecodableShape {
        /// The contents of the rule's metadata.
        public let metadata: String?
        /// The contents taken from the rule's msg field.
        public let msg: String?
        /// The unique identifier (Signature ID) of the Suricata rule.
        public let sid: String?

        @inlinable
        public init(metadata: String? = nil, msg: String? = nil, sid: String? = nil) {
            self.metadata = metadata
            self.msg = msg
            self.sid = sid
        }

        private enum CodingKeys: String, CodingKey {
            case metadata = "Metadata"
            case msg = "Msg"
            case sid = "SID"
        }
    }

    public struct RuleVariables: AWSEncodableShape & AWSDecodableShape {
        /// A list of IP addresses and address ranges, in CIDR notation.
        public let ipSets: [String: IPSet]?
        /// A list of port ranges.
        public let portSets: [String: PortSet]?

        @inlinable
        public init(ipSets: [String: IPSet]? = nil, portSets: [String: PortSet]? = nil) {
            self.ipSets = ipSets
            self.portSets = portSets
        }

        public func validate(name: String) throws {
            try self.ipSets?.forEach {
                try validate($0.key, name: "ipSets.key", parent: name, max: 32)
                try validate($0.key, name: "ipSets.key", parent: name, min: 1)
                try validate($0.key, name: "ipSets.key", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_]*$")
                try $0.value.validate(name: "\(name).ipSets[\"\($0.key)\"]")
            }
            try self.portSets?.forEach {
                try validate($0.key, name: "portSets.key", parent: name, max: 32)
                try validate($0.key, name: "portSets.key", parent: name, min: 1)
                try validate($0.key, name: "portSets.key", parent: name, pattern: "^[A-Za-z][A-Za-z0-9_]*$")
                try $0.value.validate(name: "\(name).portSets[\"\($0.key)\"]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case ipSets = "IPSets"
            case portSets = "PortSets"
        }
    }

    public struct RulesSource: AWSEncodableShape & AWSDecodableShape {
        /// Stateful inspection criteria for a domain list rule group.
        public let rulesSourceList: RulesSourceList?
        /// Stateful inspection criteria, provided in Suricata compatible rules. Suricata is an open-source threat detection framework that includes a standard rule-based language for network traffic inspection. These rules contain the inspection criteria and the action to take for traffic that matches the criteria, so this type of rule group doesn't have a separate action setting.  You can't use the priority keyword if the RuleOrder option in StatefulRuleOptions is set to  STRICT_ORDER.
        public let rulesString: String?
        /// An array of individual stateful rules inspection criteria to be used together in a stateful rule group. Use this option to specify simple Suricata rules with protocol, source and destination, ports, direction, and rule options. For information about the Suricata Rules format, see Rules Format.
        public let statefulRules: [StatefulRule]?
        /// Stateless inspection criteria to be used in a stateless rule group.
        public let statelessRulesAndCustomActions: StatelessRulesAndCustomActions?

        @inlinable
        public init(rulesSourceList: RulesSourceList? = nil, rulesString: String? = nil, statefulRules: [StatefulRule]? = nil, statelessRulesAndCustomActions: StatelessRulesAndCustomActions? = nil) {
            self.rulesSourceList = rulesSourceList
            self.rulesString = rulesString
            self.statefulRules = statefulRules
            self.statelessRulesAndCustomActions = statelessRulesAndCustomActions
        }

        public func validate(name: String) throws {
            try self.validate(self.rulesString, name: "rulesString", parent: name, max: 2000000)
            try self.statefulRules?.forEach {
                try $0.validate(name: "\(name).statefulRules[]")
            }
            try self.statelessRulesAndCustomActions?.validate(name: "\(name).statelessRulesAndCustomActions")
        }

        private enum CodingKeys: String, CodingKey {
            case rulesSourceList = "RulesSourceList"
            case rulesString = "RulesString"
            case statefulRules = "StatefulRules"
            case statelessRulesAndCustomActions = "StatelessRulesAndCustomActions"
        }
    }

    public struct RulesSourceList: AWSEncodableShape & AWSDecodableShape {
        /// Whether you want to apply allow, reject, alert, or drop behavior to the domains in your target list.  When logging is enabled and you choose Alert, traffic that matches the domain specifications  generates an alert in the firewall's logs. Then, traffic either passes, is rejected, or drops based on other rules in the firewall policy.
        public let generatedRulesType: GeneratedRulesType
        /// The domains that you want to inspect for in your traffic flows. Valid domain specifications are the following:   Explicit names. For example, abc.example.com matches only the domain abc.example.com.   Names that use a domain wildcard, which you indicate with an initial '.'. For example,.example.com matches example.com and matches all subdomains of example.com, such as abc.example.com and www.example.com.
        public let targets: [String]
        /// The protocols you want to inspect. Specify TLS_SNI for HTTPS. Specify HTTP_HOST for HTTP. You can specify either or both.
        public let targetTypes: [TargetType]

        @inlinable
        public init(generatedRulesType: GeneratedRulesType, targets: [String], targetTypes: [TargetType]) {
            self.generatedRulesType = generatedRulesType
            self.targets = targets
            self.targetTypes = targetTypes
        }

        private enum CodingKeys: String, CodingKey {
            case generatedRulesType = "GeneratedRulesType"
            case targets = "Targets"
            case targetTypes = "TargetTypes"
        }
    }

    public struct ServerCertificate: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the Certificate Manager SSL/TLS server certificate that's used for inbound SSL/TLS inspection.
        public let resourceArn: String?

        @inlinable
        public init(resourceArn: String? = nil) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
        }
    }

    public struct ServerCertificateConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the imported certificate authority (CA) certificate within Certificate Manager (ACM) to use for outbound SSL/TLS inspection. The following limitations apply:   You can use CA certificates that you imported into ACM, but you can't generate CA certificates with ACM.   You can't use certificates issued by Private Certificate Authority.   For more information about configuring certificates for outbound inspection, see Using SSL/TLS certificates with TLS inspection configurations in the Network Firewall Developer Guide.  For information about working with certificates in ACM, see Importing certificates in the Certificate Manager User Guide.
        public let certificateAuthorityArn: String?
        /// When enabled, Network Firewall checks if the server certificate presented by the server in the SSL/TLS connection has a revoked or unkown status. If the certificate has an unknown or revoked status, you must specify the actions that Network Firewall takes on outbound traffic. To check the certificate revocation status, you must also specify a CertificateAuthorityArn in ServerCertificateConfiguration.
        public let checkCertificateRevocationStatus: CheckCertificateRevocationStatusActions?
        /// A list of scopes.
        public let scopes: [ServerCertificateScope]?
        /// The list of server certificates to use for inbound SSL/TLS inspection.
        public let serverCertificates: [ServerCertificate]?

        @inlinable
        public init(certificateAuthorityArn: String? = nil, checkCertificateRevocationStatus: CheckCertificateRevocationStatusActions? = nil, scopes: [ServerCertificateScope]? = nil, serverCertificates: [ServerCertificate]? = nil) {
            self.certificateAuthorityArn = certificateAuthorityArn
            self.checkCertificateRevocationStatus = checkCertificateRevocationStatus
            self.scopes = scopes
            self.serverCertificates = serverCertificates
        }

        public func validate(name: String) throws {
            try self.validate(self.certificateAuthorityArn, name: "certificateAuthorityArn", parent: name, max: 256)
            try self.validate(self.certificateAuthorityArn, name: "certificateAuthorityArn", parent: name, min: 1)
            try self.validate(self.certificateAuthorityArn, name: "certificateAuthorityArn", parent: name, pattern: "^arn:aws")
            try self.scopes?.forEach {
                try $0.validate(name: "\(name).scopes[]")
            }
            try self.serverCertificates?.forEach {
                try $0.validate(name: "\(name).serverCertificates[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case certificateAuthorityArn = "CertificateAuthorityArn"
            case checkCertificateRevocationStatus = "CheckCertificateRevocationStatus"
            case scopes = "Scopes"
            case serverCertificates = "ServerCertificates"
        }
    }

    public struct ServerCertificateScope: AWSEncodableShape & AWSDecodableShape {
        /// The destination ports to decrypt for inspection, in Transmission Control Protocol (TCP) format. If not specified, this matches with any destination port. You can specify individual ports, for example 1994, and you can specify port ranges, such as 1990:1994.
        public let destinationPorts: [PortRange]?
        /// The destination IP addresses and address ranges to decrypt for inspection, in CIDR notation. If not specified, this
        /// matches with any destination address.
        public let destinations: [Address]?
        /// The protocols to inspect for, specified using the assigned internet protocol number (IANA)  for each protocol. If not specified, this matches with any protocol. Network Firewall currently supports only TCP.
        public let protocols: [Int]?
        /// The source ports to decrypt for inspection, in Transmission Control Protocol (TCP) format. If not specified, this matches with any source port. You can specify individual ports, for example 1994, and you can specify port ranges, such as 1990:1994.
        public let sourcePorts: [PortRange]?
        /// The source IP addresses and address ranges to decrypt for inspection, in CIDR notation. If not specified, this
        /// matches with any source address.
        public let sources: [Address]?

        @inlinable
        public init(destinationPorts: [PortRange]? = nil, destinations: [Address]? = nil, protocols: [Int]? = nil, sourcePorts: [PortRange]? = nil, sources: [Address]? = nil) {
            self.destinationPorts = destinationPorts
            self.destinations = destinations
            self.protocols = protocols
            self.sourcePorts = sourcePorts
            self.sources = sources
        }

        public func validate(name: String) throws {
            try self.destinationPorts?.forEach {
                try $0.validate(name: "\(name).destinationPorts[]")
            }
            try self.destinations?.forEach {
                try $0.validate(name: "\(name).destinations[]")
            }
            try self.protocols?.forEach {
                try validate($0, name: "protocols[]", parent: name, max: 255)
                try validate($0, name: "protocols[]", parent: name, min: 0)
            }
            try self.sourcePorts?.forEach {
                try $0.validate(name: "\(name).sourcePorts[]")
            }
            try self.sources?.forEach {
                try $0.validate(name: "\(name).sources[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case destinationPorts = "DestinationPorts"
            case destinations = "Destinations"
            case protocols = "Protocols"
            case sourcePorts = "SourcePorts"
            case sources = "Sources"
        }
    }

    public struct SourceMetadata: AWSEncodableShape & AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the rule group that your own rule group is copied from.
        public let sourceArn: String?
        /// The update token of the Amazon Web Services managed rule group that your own rule group is copied from. To determine the update token for the managed rule group, call DescribeRuleGroup.
        public let sourceUpdateToken: String?

        @inlinable
        public init(sourceArn: String? = nil, sourceUpdateToken: String? = nil) {
            self.sourceArn = sourceArn
            self.sourceUpdateToken = sourceUpdateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.sourceArn, name: "sourceArn", parent: name, max: 256)
            try self.validate(self.sourceArn, name: "sourceArn", parent: name, min: 1)
            try self.validate(self.sourceArn, name: "sourceArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.sourceUpdateToken, name: "sourceUpdateToken", parent: name, max: 1024)
            try self.validate(self.sourceUpdateToken, name: "sourceUpdateToken", parent: name, min: 1)
            try self.validate(self.sourceUpdateToken, name: "sourceUpdateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case sourceArn = "SourceArn"
            case sourceUpdateToken = "SourceUpdateToken"
        }
    }

    public struct StartAnalysisReportRequest: AWSEncodableShape {
        /// The type of traffic that will be used to generate a report.
        public let analysisType: EnabledAnalysisType
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?

        @inlinable
        public init(analysisType: EnabledAnalysisType, firewallArn: String? = nil, firewallName: String? = nil) {
            self.analysisType = analysisType
            self.firewallArn = firewallArn
            self.firewallName = firewallName
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case analysisType = "AnalysisType"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
        }
    }

    public struct StartAnalysisReportResponse: AWSDecodableShape {
        /// The unique ID of the query that ran when you requested an analysis report.
        public let analysisReportId: String

        @inlinable
        public init(analysisReportId: String) {
            self.analysisReportId = analysisReportId
        }

        private enum CodingKeys: String, CodingKey {
            case analysisReportId = "AnalysisReportId"
        }
    }

    public struct StartFlowCaptureRequest: AWSEncodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        /// Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let flowFilters: [FlowFilter]
        /// The reqested FlowOperation ignores flows with an age (in seconds) lower than MinimumFlowAgeInSeconds.
        /// You provide this for start commands.  We recommend setting this value to at least 1 minute (60 seconds) to reduce chance of capturing flows that are not yet established.
        public let minimumFlowAgeInSeconds: Int?
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?
        /// A unique identifier for the primary endpoint associated with a firewall.
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String, flowFilters: [FlowFilter], minimumFlowAgeInSeconds: Int? = nil, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowFilters = flowFilters
            self.minimumFlowAgeInSeconds = minimumFlowAgeInSeconds
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.flowFilters.forEach {
                try $0.validate(name: "\(name).flowFilters[]")
            }
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, max: 256)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, min: 5)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, pattern: "^vpce-[a-zA-Z0-9]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowFilters = "FlowFilters"
            case minimumFlowAgeInSeconds = "MinimumFlowAgeInSeconds"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct StartFlowCaptureResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String?
        /// Returns the status of the flow operation. This string is returned in the responses to start, list, and describe commands. If the status is COMPLETED_WITH_ERRORS, results may be returned with any number of Flows missing from the response.
        /// If the status is FAILED, Flows returned will be empty.
        public let flowOperationStatus: FlowOperationStatus?

        @inlinable
        public init(firewallArn: String? = nil, flowOperationId: String? = nil, flowOperationStatus: FlowOperationStatus? = nil) {
            self.firewallArn = firewallArn
            self.flowOperationId = flowOperationId
            self.flowOperationStatus = flowOperationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case flowOperationId = "FlowOperationId"
            case flowOperationStatus = "FlowOperationStatus"
        }
    }

    public struct StartFlowFlushRequest: AWSEncodableShape {
        /// The ID of the Availability Zone where the firewall is located. For example, us-east-2a. Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let availabilityZone: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        /// Defines the scope a flow operation. You can use up to 20 filters to configure a single flow operation.
        public let flowFilters: [FlowFilter]
        /// The reqested FlowOperation ignores flows with an age (in seconds) lower than MinimumFlowAgeInSeconds.
        /// You provide this for start commands.
        public let minimumFlowAgeInSeconds: Int?
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?
        /// A unique identifier for the primary endpoint associated with a firewall.
        public let vpcEndpointId: String?

        @inlinable
        public init(availabilityZone: String? = nil, firewallArn: String, flowFilters: [FlowFilter], minimumFlowAgeInSeconds: Int? = nil, vpcEndpointAssociationArn: String? = nil, vpcEndpointId: String? = nil) {
            self.availabilityZone = availabilityZone
            self.firewallArn = firewallArn
            self.flowFilters = flowFilters
            self.minimumFlowAgeInSeconds = minimumFlowAgeInSeconds
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointId = vpcEndpointId
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.flowFilters.forEach {
                try $0.validate(name: "\(name).flowFilters[]")
            }
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, max: 256)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, min: 1)
            try self.validate(self.vpcEndpointAssociationArn, name: "vpcEndpointAssociationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, max: 256)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, min: 5)
            try self.validate(self.vpcEndpointId, name: "vpcEndpointId", parent: name, pattern: "^vpce-[a-zA-Z0-9]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZone = "AvailabilityZone"
            case firewallArn = "FirewallArn"
            case flowFilters = "FlowFilters"
            case minimumFlowAgeInSeconds = "MinimumFlowAgeInSeconds"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointId = "VpcEndpointId"
        }
    }

    public struct StartFlowFlushResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// A unique identifier for the flow operation. This ID is returned in the responses to start and list commands. You provide to describe commands.
        public let flowOperationId: String?
        /// Returns the status of the flow operation. This string is returned in the responses to start, list, and describe commands. If the status is COMPLETED_WITH_ERRORS, results may be returned with any number of Flows missing from the response.
        /// If the status is FAILED, Flows returned will be empty.
        public let flowOperationStatus: FlowOperationStatus?

        @inlinable
        public init(firewallArn: String? = nil, flowOperationId: String? = nil, flowOperationStatus: FlowOperationStatus? = nil) {
            self.firewallArn = firewallArn
            self.flowOperationId = flowOperationId
            self.flowOperationStatus = flowOperationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case flowOperationId = "FlowOperationId"
            case flowOperationStatus = "FlowOperationStatus"
        }
    }

    public struct StatefulEngineOptions: AWSEncodableShape & AWSDecodableShape {
        /// Configures the amount of time that can pass without any traffic sent through the firewall before the firewall determines that the connection is idle.
        public let flowTimeouts: FlowTimeouts?
        /// Indicates how to manage the order of stateful rule evaluation for the policy. STRICT_ORDER is the recommended option, but DEFAULT_ACTION_ORDER is the default option. With STRICT_ORDER,  provide your rules in the order that you want them to be evaluated.  You can then choose one or more default actions for packets that don't match any rules.  Choose STRICT_ORDER to have the stateful rules engine determine the evaluation order of your rules.  The default action for this rule order is PASS, followed by DROP, REJECT, and ALERT actions.  Stateful rules are provided to the rule engine as Suricata compatible strings, and Suricata evaluates them based on your settings.  For more information, see Evaluation order for stateful rules in the Network Firewall Developer Guide.
        public let ruleOrder: RuleOrder?
        /// Configures how Network Firewall processes traffic when a network connection breaks midstream. Network connections can break due to disruptions in external networks or within the firewall itself.    DROP - Network Firewall fails closed and drops all subsequent traffic going to the firewall. This is the default behavior.    CONTINUE - Network Firewall continues to apply rules to the subsequent traffic without context from traffic before the break. This impacts the behavior of rules that depend on this context. For example, if you have a stateful rule to drop http traffic, Network Firewall won't match the traffic for this rule because the service won't have the context from session initialization defining the application layer protocol as HTTP. However, this behavior is rule dependent—a TCP-layer rule using a flow:stateless rule would still match, as would the aws:drop_strict default action.    REJECT - Network Firewall fails closed and drops all subsequent traffic going to the firewall. Network Firewall also sends a TCP reject packet back to your client so that the client can immediately establish a new session. Network Firewall will have context about the new session and will apply rules to the subsequent traffic.
        public let streamExceptionPolicy: StreamExceptionPolicy?

        @inlinable
        public init(flowTimeouts: FlowTimeouts? = nil, ruleOrder: RuleOrder? = nil, streamExceptionPolicy: StreamExceptionPolicy? = nil) {
            self.flowTimeouts = flowTimeouts
            self.ruleOrder = ruleOrder
            self.streamExceptionPolicy = streamExceptionPolicy
        }

        private enum CodingKeys: String, CodingKey {
            case flowTimeouts = "FlowTimeouts"
            case ruleOrder = "RuleOrder"
            case streamExceptionPolicy = "StreamExceptionPolicy"
        }
    }

    public struct StatefulRule: AWSEncodableShape & AWSDecodableShape {
        /// Defines what Network Firewall should do with the packets in a traffic flow when the flow matches the stateful rule criteria. For all actions, Network Firewall performs the specified action and discontinues stateful inspection of the traffic flow.  The actions for a stateful rule are defined as follows:     PASS - Permits the packets to go to the intended destination.    DROP - Blocks the packets from going to the intended destination and sends an alert log message, if alert logging is configured in the Firewall LoggingConfiguration.     ALERT - Sends an alert log message, if alert logging is configured in the Firewall LoggingConfiguration.  You can use this action to test a rule that you intend to use to drop traffic. You can enable the rule with ALERT action, verify in the logs that the rule is filtering as you want, then change the action to DROP.    REJECT - Drops traffic that matches the conditions of the stateful rule, and sends a TCP reset packet back to sender of the packet. A TCP reset packet is a packet with no payload and an RST bit contained in the TCP header flags. REJECT is available only for TCP traffic. This option doesn't support FTP or IMAP protocols.
        public let action: StatefulAction
        /// The stateful inspection criteria for this rule, used to inspect traffic flows.
        public let header: Header
        /// Additional options for the rule. These are the Suricata RuleOptions settings.
        public let ruleOptions: [RuleOption]

        @inlinable
        public init(action: StatefulAction, header: Header, ruleOptions: [RuleOption]) {
            self.action = action
            self.header = header
            self.ruleOptions = ruleOptions
        }

        public func validate(name: String) throws {
            try self.header.validate(name: "\(name).header")
            try self.ruleOptions.forEach {
                try $0.validate(name: "\(name).ruleOptions[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case action = "Action"
            case header = "Header"
            case ruleOptions = "RuleOptions"
        }
    }

    public struct StatefulRuleGroupOverride: AWSEncodableShape & AWSDecodableShape {
        /// The action that changes the rule group from DROP to ALERT. This only applies to managed rule groups.
        public let action: OverrideAction?

        @inlinable
        public init(action: OverrideAction? = nil) {
            self.action = action
        }

        private enum CodingKeys: String, CodingKey {
            case action = "Action"
        }
    }

    public struct StatefulRuleGroupReference: AWSEncodableShape & AWSDecodableShape {
        /// Network Firewall plans to augment the active threat defense managed rule group with an additional deep threat inspection capability. When this capability is released, Amazon Web Services will analyze service logs of network traffic processed by these rule groups to identify threat indicators across customers.  Amazon Web Services will use these threat indicators to improve the active threat defense managed rule groups and protect the security of Amazon Web Services customers and services.  Customers can opt-out of deep threat inspection at any time through the Network Firewall console or API. When customers opt out, Network Firewall  will not use the network traffic processed by those customers' active threat defense rule groups for rule group improvement.
        public let deepThreatInspection: Bool?
        /// The action that allows the policy owner to override the behavior of the rule group within a policy.
        public let override: StatefulRuleGroupOverride?
        /// An integer setting that indicates the order in which to run the stateful rule groups in a single FirewallPolicy. This setting only applies to firewall policies that specify the STRICT_ORDER rule order in the stateful engine options settings. Network Firewall evalutes each stateful rule group against a packet starting with the group that has the lowest priority setting. You must ensure that the priority settings are unique within each policy. You can change the priority settings of your rule groups at any time. To make it easier to insert rule groups later, number them so there's a wide range in between, for example use 100, 200, and so on.
        public let priority: Int?
        /// The Amazon Resource Name (ARN) of the stateful rule group.
        public let resourceArn: String

        @inlinable
        public init(deepThreatInspection: Bool? = nil, override: StatefulRuleGroupOverride? = nil, priority: Int? = nil, resourceArn: String) {
            self.deepThreatInspection = deepThreatInspection
            self.override = override
            self.priority = priority
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.priority, name: "priority", parent: name, max: 65535)
            try self.validate(self.priority, name: "priority", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case deepThreatInspection = "DeepThreatInspection"
            case override = "Override"
            case priority = "Priority"
            case resourceArn = "ResourceArn"
        }
    }

    public struct StatefulRuleOptions: AWSEncodableShape & AWSDecodableShape {
        /// Indicates how to manage the order of the rule evaluation for the rule group. DEFAULT_ACTION_ORDER is the default behavior. Stateful rules are provided to the rule engine as Suricata compatible strings, and Suricata evaluates them based on certain settings. For more information, see Evaluation order for stateful rules in the Network Firewall Developer Guide.
        public let ruleOrder: RuleOrder?

        @inlinable
        public init(ruleOrder: RuleOrder? = nil) {
            self.ruleOrder = ruleOrder
        }

        private enum CodingKeys: String, CodingKey {
            case ruleOrder = "RuleOrder"
        }
    }

    public struct StatelessRule: AWSEncodableShape & AWSDecodableShape {
        /// Indicates the order in which to run this rule relative to all of the rules that are defined for a stateless rule group. Network Firewall evaluates the rules in a rule group starting with the lowest priority setting. You must ensure that the priority settings are unique for the rule group.  Each stateless rule group uses exactly one StatelessRulesAndCustomActions object, and each StatelessRulesAndCustomActions contains exactly one StatelessRules object. To ensure unique priority settings for your rule groups, set unique priorities for the stateless rules that you define inside any single StatelessRules object. You can change the priority settings of your rules at any time. To make it easier to insert rules later, number them so there's a wide range in between, for example use 100, 200, and so on.
        public let priority: Int
        /// Defines the stateless 5-tuple packet inspection criteria and the action to take on a packet that matches the criteria.
        public let ruleDefinition: RuleDefinition

        @inlinable
        public init(priority: Int, ruleDefinition: RuleDefinition) {
            self.priority = priority
            self.ruleDefinition = ruleDefinition
        }

        public func validate(name: String) throws {
            try self.validate(self.priority, name: "priority", parent: name, max: 65535)
            try self.validate(self.priority, name: "priority", parent: name, min: 1)
            try self.ruleDefinition.validate(name: "\(name).ruleDefinition")
        }

        private enum CodingKeys: String, CodingKey {
            case priority = "Priority"
            case ruleDefinition = "RuleDefinition"
        }
    }

    public struct StatelessRuleGroupReference: AWSEncodableShape & AWSDecodableShape {
        /// An integer setting that indicates the order in which to run the stateless rule groups in a single FirewallPolicy. Network Firewall applies each stateless rule group to a packet starting with the group that has the lowest priority setting. You must ensure that the priority settings are unique within each policy.
        public let priority: Int
        /// The Amazon Resource Name (ARN) of the stateless rule group.
        public let resourceArn: String

        @inlinable
        public init(priority: Int, resourceArn: String) {
            self.priority = priority
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.priority, name: "priority", parent: name, max: 65535)
            try self.validate(self.priority, name: "priority", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
        }

        private enum CodingKeys: String, CodingKey {
            case priority = "Priority"
            case resourceArn = "ResourceArn"
        }
    }

    public struct StatelessRulesAndCustomActions: AWSEncodableShape & AWSDecodableShape {
        /// Defines an array of individual custom action definitions that are available for use by the stateless rules in this StatelessRulesAndCustomActions specification. You name each custom action that you define, and then you can use it by name in your StatelessRule RuleDefinition Actions specification.
        public let customActions: [CustomAction]?
        /// Defines the set of stateless rules for use in a stateless rule group.
        public let statelessRules: [StatelessRule]

        @inlinable
        public init(customActions: [CustomAction]? = nil, statelessRules: [StatelessRule]) {
            self.customActions = customActions
            self.statelessRules = statelessRules
        }

        public func validate(name: String) throws {
            try self.customActions?.forEach {
                try $0.validate(name: "\(name).customActions[]")
            }
            try self.statelessRules.forEach {
                try $0.validate(name: "\(name).statelessRules[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case customActions = "CustomActions"
            case statelessRules = "StatelessRules"
        }
    }

    public struct SubnetMapping: AWSEncodableShape & AWSDecodableShape {
        /// The subnet's IP address type. You can't change the IP address type after you create the subnet.
        public let ipAddressType: IPAddressType?
        /// The unique identifier for the subnet.
        public let subnetId: String

        @inlinable
        public init(ipAddressType: IPAddressType? = nil, subnetId: String) {
            self.ipAddressType = ipAddressType
            self.subnetId = subnetId
        }

        private enum CodingKeys: String, CodingKey {
            case ipAddressType = "IPAddressType"
            case subnetId = "SubnetId"
        }
    }

    public struct Summary: AWSDecodableShape {
        /// An array of RuleSummary objects containing individual rule details that had been configured by the rulegroup's SummaryConfiguration.
        public let ruleSummaries: [RuleSummary]?

        @inlinable
        public init(ruleSummaries: [RuleSummary]? = nil) {
            self.ruleSummaries = ruleSummaries
        }

        private enum CodingKeys: String, CodingKey {
            case ruleSummaries = "RuleSummaries"
        }
    }

    public struct SummaryConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Specifies the selected rule options returned by DescribeRuleGroupSummary.
        public let ruleOptions: [SummaryRuleOption]?

        @inlinable
        public init(ruleOptions: [SummaryRuleOption]? = nil) {
            self.ruleOptions = ruleOptions
        }

        private enum CodingKeys: String, CodingKey {
            case ruleOptions = "RuleOptions"
        }
    }

    public struct SyncState: AWSDecodableShape {
        /// The configuration and status for a single firewall subnet. For each configured subnet, Network Firewall creates the attachment by instantiating the firewall endpoint in the subnet so that it's ready to take traffic.
        public let attachment: Attachment?
        /// The configuration status of the firewall endpoint in a single VPC subnet. Network Firewall provides each endpoint with the rules that are configured in the firewall policy. Each time you add a subnet or modify the associated firewall policy, Network Firewall synchronizes the rules in the endpoint, so it can properly filter network traffic.
        public let config: [String: PerObjectStatus]?

        @inlinable
        public init(attachment: Attachment? = nil, config: [String: PerObjectStatus]? = nil) {
            self.attachment = attachment
            self.config = config
        }

        private enum CodingKeys: String, CodingKey {
            case attachment = "Attachment"
            case config = "Config"
        }
    }

    public struct TCPFlagField: AWSEncodableShape & AWSDecodableShape {
        /// Used in conjunction with the Masks setting to define the flags that must be set and flags that must not be set in order for the packet to match. This setting can only specify values that are also specified in the Masks setting. For the flags that are specified in the masks setting, the following must be true for the packet to match:    The ones that are set in this flags setting must be set in the packet.    The ones that are not set in this flags setting must also not be set in the packet.
        public let flags: [TCPFlag]
        /// The set of flags to consider in the inspection. To inspect all flags in the valid values list, leave this with no setting.
        public let masks: [TCPFlag]?

        @inlinable
        public init(flags: [TCPFlag], masks: [TCPFlag]? = nil) {
            self.flags = flags
            self.masks = masks
        }

        private enum CodingKeys: String, CodingKey {
            case flags = "Flags"
            case masks = "Masks"
        }
    }

    public struct TLSInspectionConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Lists the server certificate configurations that are associated with the TLS configuration.
        public let serverCertificateConfigurations: [ServerCertificateConfiguration]?

        @inlinable
        public init(serverCertificateConfigurations: [ServerCertificateConfiguration]? = nil) {
            self.serverCertificateConfigurations = serverCertificateConfigurations
        }

        public func validate(name: String) throws {
            try self.serverCertificateConfigurations?.forEach {
                try $0.validate(name: "\(name).serverCertificateConfigurations[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case serverCertificateConfigurations = "ServerCertificateConfigurations"
        }
    }

    public struct TLSInspectionConfigurationMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the TLS inspection configuration.
        public let arn: String?
        /// The descriptive name of the TLS inspection configuration. You can't change the name of a TLS inspection configuration after you create it.
        public let name: String?

        @inlinable
        public init(arn: String? = nil, name: String? = nil) {
            self.arn = arn
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case name = "Name"
        }
    }

    public struct TLSInspectionConfigurationResponse: AWSDecodableShape {
        public let certificateAuthority: TlsCertificateData?
        /// A list of the certificates associated with the TLS inspection configuration.
        public let certificates: [TlsCertificateData]?
        /// A description of the TLS inspection configuration.
        public let description: String?
        /// A complex type that contains the Amazon Web Services KMS encryption configuration settings for your TLS inspection configuration.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The last time that the TLS inspection configuration was changed.
        public let lastModifiedTime: Date?
        /// The number of firewall policies that use this TLS inspection configuration.
        public let numberOfAssociations: Int?
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// The Amazon Resource Name (ARN) of the TLS inspection configuration.
        public let tlsInspectionConfigurationArn: String
        /// A unique identifier for the TLS inspection configuration. This ID is returned in the responses to create and list commands. You provide it to operations such as update and delete.
        public let tlsInspectionConfigurationId: String
        /// The descriptive name of the TLS inspection configuration. You can't change the name of a TLS inspection configuration after you create it.
        public let tlsInspectionConfigurationName: String
        /// Detailed information about the current status of a TLSInspectionConfiguration. You can retrieve this for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration and providing the TLS inspection configuration name and ARN.
        public let tlsInspectionConfigurationStatus: ResourceStatus?

        @inlinable
        public init(certificateAuthority: TlsCertificateData? = nil, certificates: [TlsCertificateData]? = nil, description: String? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, lastModifiedTime: Date? = nil, numberOfAssociations: Int? = nil, tags: [Tag]? = nil, tlsInspectionConfigurationArn: String, tlsInspectionConfigurationId: String, tlsInspectionConfigurationName: String, tlsInspectionConfigurationStatus: ResourceStatus? = nil) {
            self.certificateAuthority = certificateAuthority
            self.certificates = certificates
            self.description = description
            self.encryptionConfiguration = encryptionConfiguration
            self.lastModifiedTime = lastModifiedTime
            self.numberOfAssociations = numberOfAssociations
            self.tags = tags
            self.tlsInspectionConfigurationArn = tlsInspectionConfigurationArn
            self.tlsInspectionConfigurationId = tlsInspectionConfigurationId
            self.tlsInspectionConfigurationName = tlsInspectionConfigurationName
            self.tlsInspectionConfigurationStatus = tlsInspectionConfigurationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case certificateAuthority = "CertificateAuthority"
            case certificates = "Certificates"
            case description = "Description"
            case encryptionConfiguration = "EncryptionConfiguration"
            case lastModifiedTime = "LastModifiedTime"
            case numberOfAssociations = "NumberOfAssociations"
            case tags = "Tags"
            case tlsInspectionConfigurationArn = "TLSInspectionConfigurationArn"
            case tlsInspectionConfigurationId = "TLSInspectionConfigurationId"
            case tlsInspectionConfigurationName = "TLSInspectionConfigurationName"
            case tlsInspectionConfigurationStatus = "TLSInspectionConfigurationStatus"
        }
    }

    public struct Tag: AWSEncodableShape & AWSDecodableShape {
        /// The part of the key:value pair that defines a tag. You can use a tag key to describe a category of information, such as "customer." Tag keys are case-sensitive.
        public let key: String
        /// The part of the key:value pair that defines a tag. You can use a tag value to describe a specific value within a category, such as "companyA" or "companyB." Tag values are case-sensitive.
        public let value: String

        @inlinable
        public init(key: String, value: String) {
            self.key = key
            self.value = value
        }

        public func validate(name: String) throws {
            try self.validate(self.key, name: "key", parent: name, max: 128)
            try self.validate(self.key, name: "key", parent: name, min: 1)
            try self.validate(self.key, name: "key", parent: name, pattern: "^.*$")
            try self.validate(self.value, name: "value", parent: name, max: 256)
            try self.validate(self.value, name: "value", parent: name, pattern: "^.*$")
        }

        private enum CodingKeys: String, CodingKey {
            case key = "Key"
            case value = "Value"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        public let tags: [Tag]

        @inlinable
        public init(resourceArn: String, tags: [Tag]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
            try self.tags.forEach {
                try $0.validate(name: "\(name).tags[]")
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 200)
            try self.validate(self.tags, name: "tags", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tags = "Tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct TlsCertificateData: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the certificate.
        public let certificateArn: String?
        /// The serial number of the certificate.
        public let certificateSerial: String?
        /// The status of the certificate.
        public let status: String?
        /// Contains details about the certificate status, including information about certificate errors.
        public let statusMessage: String?

        @inlinable
        public init(certificateArn: String? = nil, certificateSerial: String? = nil, status: String? = nil, statusMessage: String? = nil) {
            self.certificateArn = certificateArn
            self.certificateSerial = certificateSerial
            self.status = status
            self.statusMessage = statusMessage
        }

        private enum CodingKeys: String, CodingKey {
            case certificateArn = "CertificateArn"
            case certificateSerial = "CertificateSerial"
            case status = "Status"
            case statusMessage = "StatusMessage"
        }
    }

    public struct TransitGatewayAttachmentSyncState: AWSDecodableShape {
        /// The unique identifier of the transit gateway attachment.
        public let attachmentId: String?
        /// A message providing additional information about the current status, particularly useful when the transit gateway attachment is in a non-READY state. Valid values are:    CREATING - The attachment is being created    DELETING - The attachment is being deleted    DELETED - The attachment has been deleted    FAILED - The attachment creation has failed and cannot be recovered    ERROR - The attachment is in an error state that might be recoverable    READY - The attachment is active and processing traffic    PENDING_ACCEPTANCE - The attachment is waiting to be accepted    REJECTING - The attachment is in the process of being rejected    REJECTED - The attachment has been rejected   For information about troubleshooting endpoint failures, see Troubleshooting firewall endpoint failures in the Network Firewall Developer Guide.
        public let statusMessage: String?
        /// The current status of the transit gateway attachment. Valid values are:    CREATING - The attachment is being created    DELETING - The attachment is being deleted    DELETED - The attachment has been deleted    FAILED - The attachment creation has failed and cannot be recovered    ERROR - The attachment is in an error state that might be recoverable    READY - The attachment is active and processing traffic    PENDING_ACCEPTANCE - The attachment is waiting to be accepted    REJECTING - The attachment is in the process of being rejected    REJECTED - The attachment has been rejected
        public let transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus?

        @inlinable
        public init(attachmentId: String? = nil, statusMessage: String? = nil, transitGatewayAttachmentStatus: TransitGatewayAttachmentStatus? = nil) {
            self.attachmentId = attachmentId
            self.statusMessage = statusMessage
            self.transitGatewayAttachmentStatus = transitGatewayAttachmentStatus
        }

        private enum CodingKeys: String, CodingKey {
            case attachmentId = "AttachmentId"
            case statusMessage = "StatusMessage"
            case transitGatewayAttachmentStatus = "TransitGatewayAttachmentStatus"
        }
    }

    public struct UniqueSources: AWSDecodableShape {
        /// The number of unique source IP addresses that connected to a domain.
        public let count: Int?

        @inlinable
        public init(count: Int? = nil) {
            self.count = count
        }

        private enum CodingKeys: String, CodingKey {
            case count = "Count"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the resource.
        public let resourceArn: String
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 256)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^.*$")
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 200)
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case resourceArn = "ResourceArn"
            case tagKeys = "TagKeys"
        }
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateAvailabilityZoneChangeProtectionRequest: AWSEncodableShape {
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let availabilityZoneChangeProtection: Bool
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(availabilityZoneChangeProtection: Bool = false, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.availabilityZoneChangeProtection = availabilityZoneChangeProtection
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneChangeProtection = "AvailabilityZoneChangeProtection"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateAvailabilityZoneChangeProtectionResponse: AWSDecodableShape {
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let availabilityZoneChangeProtection: Bool?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(availabilityZoneChangeProtection: Bool? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.availabilityZoneChangeProtection = availabilityZoneChangeProtection
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case availabilityZoneChangeProtection = "AvailabilityZoneChangeProtection"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallAnalysisSettingsRequest: AWSEncodableShape {
        /// An optional setting indicating the specific traffic analysis types to enable on the firewall.
        public let enabledAnalysisTypes: [EnabledAnalysisType]?
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(enabledAnalysisTypes: [EnabledAnalysisType]? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.enabledAnalysisTypes = enabledAnalysisTypes
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case enabledAnalysisTypes = "EnabledAnalysisTypes"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallAnalysisSettingsResponse: AWSDecodableShape {
        /// An optional setting indicating the specific traffic analysis types to enable on the firewall.
        public let enabledAnalysisTypes: [EnabledAnalysisType]?
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(enabledAnalysisTypes: [EnabledAnalysisType]? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.enabledAnalysisTypes = enabledAnalysisTypes
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case enabledAnalysisTypes = "EnabledAnalysisTypes"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDeleteProtectionRequest: AWSEncodableShape {
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(deleteProtection: Bool = false, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.deleteProtection = deleteProtection
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case deleteProtection = "DeleteProtection"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDeleteProtectionResponse: AWSDecodableShape {
        /// A flag indicating whether it is possible to delete the firewall. A setting of TRUE indicates that the firewall is protected against deletion. Use this setting to protect against accidentally deleting a firewall that is in use. When you create a firewall, the operation initializes this flag to TRUE.
        public let deleteProtection: Bool?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(deleteProtection: Bool? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.deleteProtection = deleteProtection
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case deleteProtection = "DeleteProtection"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDescriptionRequest: AWSEncodableShape {
        /// The new description for the firewall. If you omit this setting, Network Firewall removes the description for the firewall.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(description: String? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.description = description
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallDescriptionResponse: AWSDecodableShape {
        /// A description of the firewall.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(description: String? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.description = description
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallEncryptionConfigurationRequest: AWSEncodableShape {
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(encryptionConfiguration: EncryptionConfiguration? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallEncryptionConfigurationResponse: AWSDecodableShape {
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(encryptionConfiguration: EncryptionConfiguration? = nil, firewallArn: String? = nil, firewallName: String? = nil, updateToken: String? = nil) {
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyChangeProtectionRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyChangeProtection: Bool = false, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyChangeProtectionResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against a change to the firewall policy association. Use this setting to protect against accidentally modifying the firewall policy for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let firewallPolicyChangeProtection: Bool?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, firewallPolicyChangeProtection: Bool? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.firewallPolicyChangeProtection = firewallPolicyChangeProtection
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case firewallPolicyChangeProtection = "FirewallPolicyChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyRequest: AWSEncodableShape {
        /// A description of the firewall policy.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// A complex type that contains settings for encryption of your firewall policy resources.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The updated firewall policy to use for the firewall. You can't add or remove a TLSInspectionConfiguration after you create a firewall policy. However, you can replace an existing TLS inspection configuration with another TLSInspectionConfiguration.
        public let firewallPolicy: FirewallPolicy
        /// The Amazon Resource Name (ARN) of the firewall policy. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyArn: String?
        /// The descriptive name of the firewall policy. You can't change the name of a firewall policy after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallPolicyName: String?
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(description: String? = nil, dryRun: Bool? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, firewallPolicy: FirewallPolicy, firewallPolicyArn: String? = nil, firewallPolicyName: String? = nil, updateToken: String) {
            self.description = description
            self.dryRun = dryRun
            self.encryptionConfiguration = encryptionConfiguration
            self.firewallPolicy = firewallPolicy
            self.firewallPolicyArn = firewallPolicyArn
            self.firewallPolicyName = firewallPolicyName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.firewallPolicy.validate(name: "\(name).firewallPolicy")
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, max: 256)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, min: 1)
            try self.validate(self.firewallPolicyArn, name: "firewallPolicyArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, max: 128)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, min: 1)
            try self.validate(self.firewallPolicyName, name: "firewallPolicyName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case dryRun = "DryRun"
            case encryptionConfiguration = "EncryptionConfiguration"
            case firewallPolicy = "FirewallPolicy"
            case firewallPolicyArn = "FirewallPolicyArn"
            case firewallPolicyName = "FirewallPolicyName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateFirewallPolicyResponse: AWSDecodableShape {
        /// The high-level properties of a firewall policy. This, along with the FirewallPolicy, define the policy. You can retrieve all objects for a firewall policy by calling DescribeFirewallPolicy.
        public let firewallPolicyResponse: FirewallPolicyResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the firewall policy. The token marks the state of the policy resource at the time of the request.  To make changes to the policy, you provide the token in your request. Network Firewall uses the token to ensure that the policy hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall policy again to get a current copy of it with current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(firewallPolicyResponse: FirewallPolicyResponse, updateToken: String) {
            self.firewallPolicyResponse = firewallPolicyResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallPolicyResponse = "FirewallPolicyResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateLoggingConfigurationRequest: AWSEncodableShape {
        /// A boolean that lets you enable or disable the detailed firewall monitoring dashboard on the firewall.  The monitoring dashboard provides comprehensive visibility into your firewall's flow logs and alert logs.  After you enable detailed monitoring, you can access these dashboards directly from the Monitoring page of the Network Firewall console.  Specify TRUE to enable the the detailed monitoring dashboard on the firewall.  Specify FALSE to disable the the detailed monitoring dashboard on the firewall.
        public let enableMonitoringDashboard: Bool?
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// Defines how Network Firewall performs logging for a firewall. If you omit this setting, Network Firewall disables logging for the firewall.
        public let loggingConfiguration: LoggingConfiguration?

        @inlinable
        public init(enableMonitoringDashboard: Bool? = nil, firewallArn: String? = nil, firewallName: String? = nil, loggingConfiguration: LoggingConfiguration? = nil) {
            self.enableMonitoringDashboard = enableMonitoringDashboard
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.loggingConfiguration = loggingConfiguration
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.loggingConfiguration?.validate(name: "\(name).loggingConfiguration")
        }

        private enum CodingKeys: String, CodingKey {
            case enableMonitoringDashboard = "EnableMonitoringDashboard"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case loggingConfiguration = "LoggingConfiguration"
        }
    }

    public struct UpdateLoggingConfigurationResponse: AWSDecodableShape {
        /// A boolean that reflects whether or not the firewall monitoring dashboard is enabled on a firewall.  Returns TRUE when the firewall monitoring dashboard is enabled on the firewall.  Returns FALSE when the firewall monitoring dashboard is not enabled on the firewall.
        public let enableMonitoringDashboard: Bool?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        public let loggingConfiguration: LoggingConfiguration?

        @inlinable
        public init(enableMonitoringDashboard: Bool? = nil, firewallArn: String? = nil, firewallName: String? = nil, loggingConfiguration: LoggingConfiguration? = nil) {
            self.enableMonitoringDashboard = enableMonitoringDashboard
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.loggingConfiguration = loggingConfiguration
        }

        private enum CodingKeys: String, CodingKey {
            case enableMonitoringDashboard = "EnableMonitoringDashboard"
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case loggingConfiguration = "LoggingConfiguration"
        }
    }

    public struct UpdateRuleGroupRequest: AWSEncodableShape {
        /// Indicates whether you want Network Firewall to analyze the stateless rules in the rule group for rule behavior such as asymmetric routing. If set to TRUE, Network Firewall runs the analysis and then updates the rule group for you. To run the stateless rule group analyzer without updating the rule group, set DryRun to TRUE.
        public let analyzeRuleGroup: Bool?
        /// A description of the rule group.
        public let description: String?
        /// Indicates whether you want Network Firewall to just check the validity of the request, rather than run the request.  If set to TRUE, Network Firewall checks whether the request can run successfully, but doesn't actually make the requested changes. The call returns the value that the request would return if you ran it with dry run set to FALSE, but doesn't make additions or changes to your resources. This option allows you to make sure that you have the required permissions to run the request and that your request parameters are valid.  If set to FALSE, Network Firewall makes the requested changes to your resources.
        public let dryRun: Bool?
        /// A complex type that contains settings for encryption of your rule group resources.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// An object that defines the rule group rules.   You must provide either this rule group setting or a Rules setting, but not both.
        public let ruleGroup: RuleGroup?
        /// The Amazon Resource Name (ARN) of the rule group. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupArn: String?
        /// The descriptive name of the rule group. You can't change the name of a rule group after you create it. You must specify the ARN or the name, and you can specify both.
        public let ruleGroupName: String?
        /// A string containing stateful rule group rules specifications in Suricata flat format, with one rule
        /// per line. Use this to import your existing Suricata compatible rule groups.   You must provide either this rules setting or a populated RuleGroup setting, but not both.   You can provide your rule group specification in Suricata flat format through this setting when you create or update your rule group. The call
        /// response returns a RuleGroup object that Network Firewall has populated from your string.
        public let rules: String?
        /// A complex type that contains metadata about the rule group that your own rule group is copied from. You can use the metadata to keep track of updates made to the originating rule group.
        public let sourceMetadata: SourceMetadata?
        /// Updates the selected summary configuration for a rule group. Changes affect subsequent responses from DescribeRuleGroupSummary.
        public let summaryConfiguration: SummaryConfiguration?
        /// Indicates whether the rule group is stateless or stateful. If the rule group is stateless, it contains
        /// stateless rules. If it is stateful, it contains stateful rules.   This setting is required for requests that do not include the RuleGroupARN.
        public let type: RuleGroupType?
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(analyzeRuleGroup: Bool? = nil, description: String? = nil, dryRun: Bool? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, ruleGroup: RuleGroup? = nil, ruleGroupArn: String? = nil, ruleGroupName: String? = nil, rules: String? = nil, sourceMetadata: SourceMetadata? = nil, summaryConfiguration: SummaryConfiguration? = nil, type: RuleGroupType? = nil, updateToken: String) {
            self.analyzeRuleGroup = analyzeRuleGroup
            self.description = description
            self.dryRun = dryRun
            self.encryptionConfiguration = encryptionConfiguration
            self.ruleGroup = ruleGroup
            self.ruleGroupArn = ruleGroupArn
            self.ruleGroupName = ruleGroupName
            self.rules = rules
            self.sourceMetadata = sourceMetadata
            self.summaryConfiguration = summaryConfiguration
            self.type = type
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.ruleGroup?.validate(name: "\(name).ruleGroup")
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, max: 256)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, min: 1)
            try self.validate(self.ruleGroupArn, name: "ruleGroupArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, max: 128)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, min: 1)
            try self.validate(self.ruleGroupName, name: "ruleGroupName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.rules, name: "rules", parent: name, max: 2000000)
            try self.sourceMetadata?.validate(name: "\(name).sourceMetadata")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case analyzeRuleGroup = "AnalyzeRuleGroup"
            case description = "Description"
            case dryRun = "DryRun"
            case encryptionConfiguration = "EncryptionConfiguration"
            case ruleGroup = "RuleGroup"
            case ruleGroupArn = "RuleGroupArn"
            case ruleGroupName = "RuleGroupName"
            case rules = "Rules"
            case sourceMetadata = "SourceMetadata"
            case summaryConfiguration = "SummaryConfiguration"
            case type = "Type"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateRuleGroupResponse: AWSDecodableShape {
        /// The high-level properties of a rule group. This, along with the RuleGroup, define the rule group. You can retrieve all objects for a rule group by calling DescribeRuleGroup.
        public let ruleGroupResponse: RuleGroupResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the rule group. The token marks the state of the rule group resource at the time of the request.  To make changes to the rule group, you provide the token in your request. Network Firewall uses the token to ensure that the rule group hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the rule group again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(ruleGroupResponse: RuleGroupResponse, updateToken: String) {
            self.ruleGroupResponse = ruleGroupResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case ruleGroupResponse = "RuleGroupResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateSubnetChangeProtectionRequest: AWSEncodableShape {
        /// The Amazon Resource Name (ARN) of the firewall. You must specify the ARN or the name, and you can specify both.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it. You must specify the ARN or the name, and you can specify both.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetChangeProtection: Bool = false, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetChangeProtection = subnetChangeProtection
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, max: 256)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, min: 1)
            try self.validate(self.firewallArn, name: "firewallArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.firewallName, name: "firewallName", parent: name, max: 128)
            try self.validate(self.firewallName, name: "firewallName", parent: name, min: 1)
            try self.validate(self.firewallName, name: "firewallName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetChangeProtection = "SubnetChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateSubnetChangeProtectionResponse: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String?
        /// The descriptive name of the firewall. You can't change the name of a firewall after you create it.
        public let firewallName: String?
        /// A setting indicating whether the firewall is protected against changes to the subnet associations. Use this setting to protect against accidentally modifying the subnet associations for a firewall that is in use. When you create a firewall, the operation initializes this setting to TRUE.
        public let subnetChangeProtection: Bool?
        /// An optional token that you can use for optimistic locking. Network Firewall returns a token to your requests that access the firewall. The token marks the state of the firewall resource at the time of the request.  To make an unconditional change to the firewall, omit the token in your update request. Without the token, Network Firewall performs your updates regardless of whether the firewall has changed since you last retrieved it. To make a conditional change to the firewall, provide the token in your update request. Network Firewall uses the token to ensure that the firewall hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the firewall again to get a current copy of it with a new token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String?

        @inlinable
        public init(firewallArn: String? = nil, firewallName: String? = nil, subnetChangeProtection: Bool? = nil, updateToken: String? = nil) {
            self.firewallArn = firewallArn
            self.firewallName = firewallName
            self.subnetChangeProtection = subnetChangeProtection
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case firewallArn = "FirewallArn"
            case firewallName = "FirewallName"
            case subnetChangeProtection = "SubnetChangeProtection"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateTLSInspectionConfigurationRequest: AWSEncodableShape {
        /// A description of the TLS inspection configuration.
        public let description: String?
        /// A complex type that contains the Amazon Web Services KMS encryption configuration settings for your TLS inspection configuration.
        public let encryptionConfiguration: EncryptionConfiguration?
        /// The object that defines a TLS inspection configuration. This, along with TLSInspectionConfigurationResponse, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.  Network Firewall uses a TLS inspection configuration to decrypt traffic. Network Firewall re-encrypts the traffic before sending it to its destination. To use a TLS inspection configuration, you add it to a new Network Firewall firewall policy, then you apply the firewall policy to a firewall. Network Firewall acts as a proxy service to decrypt and inspect the traffic traveling through your firewalls. You can reference a TLS inspection configuration from more than one firewall policy, and you can use a firewall policy in more than one firewall. For more information about using TLS inspection configurations, see  Inspecting SSL/TLS traffic with TLS
        /// inspection configurations in the Network Firewall Developer Guide.
        public let tlsInspectionConfiguration: TLSInspectionConfiguration
        /// The Amazon Resource Name (ARN) of the TLS inspection configuration.
        public let tlsInspectionConfigurationArn: String?
        /// The descriptive name of the TLS inspection configuration. You can't change the name of a TLS inspection configuration after you create it.
        public let tlsInspectionConfigurationName: String?
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the TLS inspection configuration. The token marks the state of the TLS inspection configuration resource at the time of the request.  To make changes to the TLS inspection configuration, you provide the token in your request. Network Firewall uses the token to ensure that the TLS inspection configuration hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the TLS inspection configuration again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(description: String? = nil, encryptionConfiguration: EncryptionConfiguration? = nil, tlsInspectionConfiguration: TLSInspectionConfiguration, tlsInspectionConfigurationArn: String? = nil, tlsInspectionConfigurationName: String? = nil, updateToken: String) {
            self.description = description
            self.encryptionConfiguration = encryptionConfiguration
            self.tlsInspectionConfiguration = tlsInspectionConfiguration
            self.tlsInspectionConfigurationArn = tlsInspectionConfigurationArn
            self.tlsInspectionConfigurationName = tlsInspectionConfigurationName
            self.updateToken = updateToken
        }

        public func validate(name: String) throws {
            try self.validate(self.description, name: "description", parent: name, max: 512)
            try self.validate(self.description, name: "description", parent: name, pattern: "^.*$")
            try self.encryptionConfiguration?.validate(name: "\(name).encryptionConfiguration")
            try self.tlsInspectionConfiguration.validate(name: "\(name).tlsInspectionConfiguration")
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, max: 256)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationArn, name: "tlsInspectionConfigurationArn", parent: name, pattern: "^arn:aws")
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, max: 128)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, min: 1)
            try self.validate(self.tlsInspectionConfigurationName, name: "tlsInspectionConfigurationName", parent: name, pattern: "^[a-zA-Z0-9-]+$")
            try self.validate(self.updateToken, name: "updateToken", parent: name, max: 1024)
            try self.validate(self.updateToken, name: "updateToken", parent: name, min: 1)
            try self.validate(self.updateToken, name: "updateToken", parent: name, pattern: "^([0-9a-f]{8})-([0-9a-f]{4}-){3}([0-9a-f]{12})$")
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case encryptionConfiguration = "EncryptionConfiguration"
            case tlsInspectionConfiguration = "TLSInspectionConfiguration"
            case tlsInspectionConfigurationArn = "TLSInspectionConfigurationArn"
            case tlsInspectionConfigurationName = "TLSInspectionConfigurationName"
            case updateToken = "UpdateToken"
        }
    }

    public struct UpdateTLSInspectionConfigurationResponse: AWSDecodableShape {
        /// The high-level properties of a TLS inspection configuration. This, along with the TLSInspectionConfiguration, define the TLS inspection configuration. You can retrieve all objects for a TLS inspection configuration by calling DescribeTLSInspectionConfiguration.
        public let tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse
        /// A token used for optimistic locking. Network Firewall returns a token to your requests that access the TLS inspection configuration. The token marks the state of the TLS inspection configuration resource at the time of the request.  To make changes to the TLS inspection configuration, you provide the token in your request. Network Firewall uses the token to ensure that the TLS inspection configuration hasn't changed since you last retrieved it. If it has changed, the operation fails with an InvalidTokenException. If this happens, retrieve the TLS inspection configuration again to get a current copy of it with a current token. Reapply your changes as needed, then try the operation again using the new token.
        public let updateToken: String

        @inlinable
        public init(tlsInspectionConfigurationResponse: TLSInspectionConfigurationResponse, updateToken: String) {
            self.tlsInspectionConfigurationResponse = tlsInspectionConfigurationResponse
            self.updateToken = updateToken
        }

        private enum CodingKeys: String, CodingKey {
            case tlsInspectionConfigurationResponse = "TLSInspectionConfigurationResponse"
            case updateToken = "UpdateToken"
        }
    }

    public struct VpcEndpointAssociation: AWSDecodableShape {
        /// A description of the VPC endpoint association.
        public let description: String?
        /// The Amazon Resource Name (ARN) of the firewall.
        public let firewallArn: String
        public let subnetMapping: SubnetMapping
        /// The key:value pairs to associate with the resource.
        public let tags: [Tag]?
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String
        /// The unique identifier of the VPC endpoint association.
        public let vpcEndpointAssociationId: String?
        /// The unique identifier of the VPC for the endpoint association.
        public let vpcId: String

        @inlinable
        public init(description: String? = nil, firewallArn: String, subnetMapping: SubnetMapping, tags: [Tag]? = nil, vpcEndpointAssociationArn: String, vpcEndpointAssociationId: String? = nil, vpcId: String) {
            self.description = description
            self.firewallArn = firewallArn
            self.subnetMapping = subnetMapping
            self.tags = tags
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
            self.vpcEndpointAssociationId = vpcEndpointAssociationId
            self.vpcId = vpcId
        }

        private enum CodingKeys: String, CodingKey {
            case description = "Description"
            case firewallArn = "FirewallArn"
            case subnetMapping = "SubnetMapping"
            case tags = "Tags"
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
            case vpcEndpointAssociationId = "VpcEndpointAssociationId"
            case vpcId = "VpcId"
        }
    }

    public struct VpcEndpointAssociationMetadata: AWSDecodableShape {
        /// The Amazon Resource Name (ARN) of a VPC endpoint association.
        public let vpcEndpointAssociationArn: String?

        @inlinable
        public init(vpcEndpointAssociationArn: String? = nil) {
            self.vpcEndpointAssociationArn = vpcEndpointAssociationArn
        }

        private enum CodingKeys: String, CodingKey {
            case vpcEndpointAssociationArn = "VpcEndpointAssociationArn"
        }
    }

    public struct VpcEndpointAssociationStatus: AWSDecodableShape {
        /// The list of the Availability Zone sync states for all subnets that are defined by the firewall.
        public let associationSyncState: [String: AZSyncState]?
        /// The readiness of the configured firewall endpoint to handle network traffic.
        public let status: FirewallStatusValue

        @inlinable
        public init(associationSyncState: [String: AZSyncState]? = nil, status: FirewallStatusValue) {
            self.associationSyncState = associationSyncState
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case associationSyncState = "AssociationSyncState"
            case status = "Status"
        }
    }
}

// MARK: - Errors

/// Error enum for NetworkFirewall
public struct NetworkFirewallErrorType: AWSErrorType {
    enum Code: String {
        case insufficientCapacityException = "InsufficientCapacityException"
        case internalServerError = "InternalServerError"
        case invalidOperationException = "InvalidOperationException"
        case invalidRequestException = "InvalidRequestException"
        case invalidResourcePolicyException = "InvalidResourcePolicyException"
        case invalidTokenException = "InvalidTokenException"
        case limitExceededException = "LimitExceededException"
        case logDestinationPermissionException = "LogDestinationPermissionException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case resourceOwnerCheckException = "ResourceOwnerCheckException"
        case throttlingException = "ThrottlingException"
        case unsupportedOperationException = "UnsupportedOperationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize NetworkFirewall
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// Amazon Web Services doesn't currently have enough available capacity to fulfill your request. Try your request later.
    public static var insufficientCapacityException: Self { .init(.insufficientCapacityException) }
    /// Your request is valid, but Network Firewall couldn't perform the operation because of a system problem. Retry your request.
    public static var internalServerError: Self { .init(.internalServerError) }
    /// The operation failed because it's not valid. For example, you might have tried to delete a rule group or firewall policy that's in use.
    public static var invalidOperationException: Self { .init(.invalidOperationException) }
    /// The operation failed because of a problem with your request. Examples include:    You specified an unsupported parameter name or value.   You tried to update a property with a value that isn't among the available types.   Your request references an ARN that is malformed, or corresponds to a resource that isn't valid in the context of the request.
    public static var invalidRequestException: Self { .init(.invalidRequestException) }
    /// The policy statement failed validation.
    public static var invalidResourcePolicyException: Self { .init(.invalidResourcePolicyException) }
    /// The token you provided is stale or isn't valid for the operation.
    public static var invalidTokenException: Self { .init(.invalidTokenException) }
    /// Unable to perform the operation because doing so would violate a limit setting.
    public static var limitExceededException: Self { .init(.limitExceededException) }
    /// Unable to send logs to a configured logging destination.
    public static var logDestinationPermissionException: Self { .init(.logDestinationPermissionException) }
    /// Unable to locate a resource using the parameters that you provided.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// Unable to change the resource because your account doesn't own it.
    public static var resourceOwnerCheckException: Self { .init(.resourceOwnerCheckException) }
    /// Unable to process the request due to throttling limitations.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The operation you requested isn't supported by Network Firewall.
    public static var unsupportedOperationException: Self { .init(.unsupportedOperationException) }
}

extension NetworkFirewallErrorType: Equatable {
    public static func == (lhs: NetworkFirewallErrorType, rhs: NetworkFirewallErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension NetworkFirewallErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
